我正在寻找一种过滤插播广告但使用优先级的选项。
以下是伪代码:
results.stream().filter(prio1).ifNotFound(filter(prio2)).collect(toList())
结果列表应通过称为“
prio1
”的第一个标准进行过滤,如果找不到匹配项,则应使用第二个过滤器尝试对称为prio2
的第二个条件进行过滤,然后应收集结果如何在Java 8中使用流实现此目标?
我正在寻找一条流线型。
最佳答案
您将需要对结果进行两次stream()
编码,但以下内容应作为一种方法起作用:
results.stream().filter(results.stream().anyMatch(prio1) ? prio1 : prio2).collect(Collectors.toList());
(向flakes贷记,以便首先使用类似的策略发布多文件。)
编辑:既然发现了一些出色的新答案,我想我会参考此线程的某些其他部分来对此多流/
anyMatch
策略做一个简短的辩护:anyMatch
经过优化,可以早日返回,因此花了最少的时间读取额外的流(尤其是prio1
可能匹配的情况)。实际上,在后备情况(anyMatch
)情况下,prio2
只会读取整个流,因此对于平均运行,您只需要遍历一小部分的列表长度。 Collectors.groupingBy(...)
方法都会构造一个Map和两个List,而上述方法最多只能创建一个List。随着results
大小的增加,此处的内存开销差异将变得非常重要。分组是针对整个流完成的,因此,即使第一个元素碰巧通过了prio1
,每个元素也都必须根据prio1.or(prio2)
和prio1
进行检查。 groupingBy
不解决prio1
和prio2
不互斥的情况。如果prio2.test(e)
可以为传递true
的某些e
返回prio1
,则这些元素将在后备prio2
列表中丢失。一次使用anyMatch
和一个过滤器可以避免此问题。