我正在寻找一种过滤插播广告但使用优先级的选项。

以下是伪代码:

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策略做一个简短的辩护:
  • As pointed out by eckesanyMatch经过优化,可以早日返回,因此花了最少的时间读取额外的流(尤其是prio1可能匹配的情况)。实际上,在后备情况(anyMatch)情况下,prio2只会读取整个流,因此对于平均运行,您只需要遍历一小部分的列表长度。
  • 在每种情况下,使用Collectors.groupingBy(...)方法都会构造一个Map和两个List,而上述方法最多只能创建一个List。随着results大小的增加,此处的内存开销差异将变得非常重要。分组是针对整个流完成的,因此,即使第一个元素碰巧通过了prio1,每个元素也都必须根据prio1.or(prio2)prio1进行检查。
  • groupingBy不解决prio1prio2不互斥的情况。如果prio2.test(e)可以为传递true的某些e返回prio1,则这些元素将在后备prio2列表中丢失。一次使用anyMatch和一个过滤器可以避免此问题。
  • 对我来说,上述方法的行长和复杂度似乎要好得多。
  • 07-26 00:06