如何解决如果先前的过滤器导致流为空,则对原始流进行过滤
如果先前的过滤器返回空流,则想出一种在原始流上应用过滤器的方法。例如:
List<Integer> numbers = ...
List<Integer> filterednums = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
if (filterednums.isEmpty()) {
filterednums = numbers.stream()
.filter(n -> n % 3 == 0)
.collect(Collectors.toList());
}
if (filterednums.isEmpty()) {
filterednums = numbers.stream()
.filter(n -> n % 5 == 0)
.collect(Collectors.toList());
}
给出数字列表(例如1、3、5、15、21)将得出3、15、21。
我的数字示例是我尝试做的事情的简化版本,但传达了相同的概念。我可以创建一个收集器来执行此操作,但是总的来说,我觉得我缺少一些简单的东西。理想情况下,我希望该解决方案能够在流中使用,以便我可以继续对其执行其他流操作。在这种情况下,也许我想将其简化为一个总和或映射,在其中将每个数字乘以并收集到一个列表中。
解决方法
您可能有一个包含谓词的流,并用它们中的每一个过滤您的集合,直到过滤操作的结果返回一个非空列表:
getByRole
这会将每个谓词转换为过滤后的列表(通过将当前谓词应用于原始列表)。丢弃已过滤的空列表,直到谓词生成非空列表或谓词全部消耗为止。
,这里是您可以组合条件的一种方式:
List<Integer> divs = Arrays.asList(2,3,5);
List<Integer> filteredNums = divs.stream()
.filter(d -> numbers.stream().anyMatch(n -> n % d == 0))
.findFirst()
.map(d -> numbers.stream().filter(n -> n % d == 0).collect(Collectors.toList()))
.orElse(Collections.EMPTY_LIST);
这个想法是用您要使用的分隔符创建一个列表,然后找到第一个分隔符(如果存在),然后过滤所有数字或返回一个空列表
,List<Predicate<Integer>> predicates = Arrays.asList(n -> n % 2 == 0,n -> n % 3 == 0,n -> n % 5 == 0);
List<Integer> numbers = Arrays.asList(11,12,15,4,43);
List<Integer> integers = predicates.stream()
.map(p -> numbers.stream().filter(n -> p.test(n)).collect(Collectors.toList()))
.filter(l -> !l.isEmpty())
.findFirst().orElse(Collections.emptyList());
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。