当前位置: 首页 > 面试题库 >

如何将多个谓词应用于java.util.Stream?

燕照
2023-03-14
问题内容

如何将多个谓词应用于一个java.util.Stream's filter()方法?

这就是我现在要做的,但是我真的不喜欢它。我有一个Collection东西,我需要根据Collection过滤器(谓词)减少东西的数量:

Collection<Thing> things = someGenerator.someMethod();
List<Thing> filtered = things.parallelStream().filter(p -> {
   for (Filter f : filtersCollection) {
      if (f.test(p))
        return true;
   }
   return false;
}).collect(Collectors.toList());

我知道,如果我预先知道过滤器的数量,则可以执行以下操作:

List<Thing> filtered = things.parallelStream().filter(filter1).or(filter2).or(filter3)).collect(Collectors.toList());

但是如何在不混合编程样式的情况下应用未知数量的谓词?众所周知,它看起来有点丑陋。


问题答案:

我假设您Filter的类型不同于java.util.function.Predicate,这意味着需要对其进行调整。一种可行的方法如下:

things.stream().filter(t -> filtersCollection.stream().anyMatch(f -> f.test(t)));

这会为每个谓词评估重新创建过滤器流带来轻微的性能损失。为避免这种情况,您可以将每个过滤器包装到中Predicate并组成它们:

things.stream().filter(filtersCollection.stream().<Predicate>map(f -> f::test)
                       .reduce(Predicate::or).orElse(t->false));

但是,由于现在每个过滤器都落后于自己html" target="_blank">Predicate,引入了更高级别的间接访问,因此尚不清楚哪种方法具有更好的整体性能。

没有适应性的关注(如果您Filter碰巧是Predicate),问题陈述将变得更加简单,第二种方法显然会胜出:

things.stream().filter(
   filtersCollection.stream().reduce(Predicate::or).orElse(t->true)
);


 类似资料:
  • 在我用Talend 6.5构建的路由中,使用了Saxon 9.5 jar,因此所有XPath谓词都使用Saxon进行评估。 升级到Talend 7.1以使用较新的Camel版本后,现在使用的是saxon 9.8版本,我从中了解到(带有saxon的Apache Camel Xpath 2.0在RouteBuilder/Predicates中似乎不起作用),9.6不会自动使用。 理想情况下,我希望Ca

  • 我试图利用Querydsl从表中获取一些结果。到目前为止,这是我尝试过的-- 如何在上面的中合并以便只获取第一个结果?

  • 问题内容: 我希望两个名称不同的类在CSS中具有相同的属性。我不想重复代码。 由于两个类都在做同一件事,因此我应该能够将其合并为一个。我怎样才能做到这一点? 问题答案: 是您要寻找的。

  • 在Java 8中,您可以使用方法引用来过滤流,例如: 有没有一种方法可以创建一个方法引用,它是现有方法引用的否定,例如: 我可以像下面这样创建方法,但我想知道JDK是否提供了类似的东西。

  • 问题内容: 在某些情况下,我应该对一个div使用多种背景颜色。对我来说,比使用背景图片或其他div更好。但是,我找不到更简单的CSS使用方式。因此,我需要某些情况的帮助。 (1)我要建立“ A”。为此,我写道: 但是,编写完该代码后,它将类似于“ B”。但是,我要像“ A”一样。那么,如何通过css / css3做到这一点(不增加更多的div)? (2)是否可以使一部分比另一部分小?例如,在“ C

  • 问题内容: 我有一个包含两个类的元素,一个叫做“ rotate”,它将旋转元素360度,另一个叫做“ doublesize”,它将元素放大两倍于其正常大小: 我猜这是行不通的,因为这些类会覆盖彼此的属性? 我知道我可以很容易地在一条CSS规则中做到这一点,例如: 但是我希望能够在可能的情况下分别应用每个类。 问题答案: 我猜这是行不通的,因为这些类会覆盖彼此的属性? 正确。作为级联工作方式的副作用