如何将多个谓词应用于 java.util.Stream? [英] How to apply multiple predicates to a java.util.Stream?

查看:20
本文介绍了如何将多个谓词应用于 java.util.Stream?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How can I apply multiple predicates to a java.util.Stream's filter() method?

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

This is what I do now, but I don't really like it. I have a Collection of things and I need to reduce the number of things based on the Collection of filters (predicates):

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());

我知道如果我预先知道过滤器的数量,我可以做这样的事情:

I know that if I knew number of filters up-front, I could do something like this:

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

但是如何在不混合编程风格的情况下应用未知数量的谓词?要知道它看起来有点丑......

But how can I apply unknown number of predicates without mixing programming styles? For know it looks sort of ugly...

推荐答案

我假设您的 Filter 是一种不同于 java.util.function.Predicate 的类型,后者意味着它需要适应它.一种可行的方法如下:

I am assuming your Filter is a type distinct from java.util.function.Predicate, which means it needs to be adapted to it. One approach which will work goes like this:

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

这会导致为每个谓词评估重新创建过滤器流的轻微性能损失.为了避免这种情况,您可以将每个过滤器包装成一个 Predicate 并组合它们:

This incurs a slight performance hit of recreating the filter stream for each predicate evaluation. To avoid that you could wrap each filter into a Predicate and compose them:

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

然而,由于现在每个过滤器都在它自己的Predicate之后,引入了一个更多的间接级别,因此尚不清楚哪种方法会具有更好的整体性能.

However, since now each filter is behind its own Predicate, introducing one more level of indirection, it is not clear-cut which approach would have better overall performance.

如果没有自适应问题(如果您的 Filter 恰好是一个 Predicate),问题陈述就会变得简单得多,第二种方法显然胜出:

Without the adapting concern (if your Filter happens to be a Predicate) the problem statement becomes much simpler and the second approach clearly wins out:

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

这篇关于如何将多个谓词应用于 java.util.Stream?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆