在Java 8中懒惰地返回第一个非空列表

我有N个列表从存储库返回数据。 我想返回这三个列表中的第一个非空(每个列表执行不同的SQL来获取数据)。

问题是我想懒得这样做,所以如果我已经找到了可接受的结果,我就不需要在数据库上执行SQL。 我的代码是(修改过的)

@Override public List dataService(Data data) { return firstNonEmptyList(repository.getDataWayOne(data.getParameter()), repository.getDataWayTwo(data.getParameter()), repository.getDataWayThree(data.getParameter().getAcessoryParameter()) Collections.singletonList(repository.getDefaultData(data.getParameter())); } @SafeVarargs private final List firstNonEmptyList(List... lists) { for (List list : lists) { if (!list.isEmpty()) { return list; } } return null; } 

这有效,但它不是懒惰的。 有任何想法吗?

您可以创建供应商流并按照订单顺序对其进行评估,直到找到结果:

 return Stream.>>of( () -> repository.getDataWayOne(data.getParameter()), () -> repository.getDataWayTwo(data.getParameter()), () -> repository.getDataWayThree(data.getParameter().getAcessoryParameter()), () -> Collections.singletonList(repository.getDefaultData(data.getParameter())) ) .map(Supplier::get) .filter(l -> !l.isEmpty()) .findFirst() .orElse(null); 

每个供应商都定义了如何访问结果集,而不是在执行map()之前实际尝试它。 由于filter()map()无状态操作,因此在尝试下一个供应商之前,将调用每个供应商并validation其结果。 如果找到非空结果,则流将立即终止,因为findFirst()正在短路

如果溪流不是你的一杯茶,你仍然可以使用lambdas来实现你想要的,只需对原始代码稍作修改即可。

 public List dataService(Data data) { return firstNonEmptyList( () -> repository.getDataWayOne(data.getParameter()), () -> repository.getDataWayTwo(data.getParameter()), () -> repository.getDataWayThree(data.getParameter().getAcessoryParameter()), () -> Collections.singletonList(repository.getDefaultData(data.getParameter())) ); } private final List firstNonEmptyList(Supplier>... listSuppliers) { for (Supplier> supplier : listSuppliers) { List list = supplier.get(); if (!list.isEmpty()) { return list; } } return null; }