如何将过滤器集合应用到 Java 流?

stw*_*sel 4 java java-8 java-stream

如何将谓词集合应用到 Java 流?

下面的代码将说明我的想法:

final Collection<Predicate<MyObject>> filters = getFilters();
final Stream<MyObject> oStream = getMyObjectStream();
oStream
   .filterAll(filters) // <- this one doesn't exist
   .forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

我目前正在使用带有经典循环的函数.filter(m -> applyAllFilters(m, filters)),但想知道是否有更“流式”的方式?

boolean applyAllFilters(final MyObject m, final Collection<Predicate<MyObject>> filters) {
   Iterator Predicate<MyObject> iter = filters.iterator();
   while(iter.hasNext()) {
      Predicate<MyObject> p = iter.next();
      if (!p.test(m)) {
         return false;
      }
   } 
  return true;
}
Run Code Online (Sandbox Code Playgroud)

Pab*_*mez 8

您可以简单地将所有谓词简化为一个与所有谓词进行与运算的谓词,如下所示:

oStream
    .filter(filters.stream().reduce(Predicate::and).orElseThrow())
    .forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

或者,如果您希望过滤器列表在某些情况下为空,您可以这样做:

oStream
    .filter(filters.stream().reduce(o -> true, Predicate::and))
    .forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

  • @stwissel是的,[文档](https://docs.oracle.com/javase/8/docs/api/java/util/function/Predicate.html#and-java.util.function.Predicate-) 说出来返回*“一个组合谓词,表示该谓词和另一个谓词的短路逻辑与”*。 (2认同)