Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to apply a collection of filters to a Java stream?

How can I apply a collection of predicates to a Java stream?

The following code shall illustrate what I have in mind:

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

I'm currently using a function .filter(m -> applyAllFilters(m, filters)) with a classic loop, but wonder if there is a more "streamy" way?

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;
}
like image 566
stwissel Avatar asked Dec 22 '22 15:12

stwissel


1 Answers

You can simply reduce all the predicates into one single Predicate that is anded with all of them like this:

oStream
    .filter(filters.stream().reduce(Predicate::and).orElseThrow())
    .forEach(System.out::println);

Alternatively, if you expect the list of filters to be empty in some cases, you could do it this way:

oStream
    .filter(filters.stream().reduce(o -> true, Predicate::and))
    .forEach(System.out::println);
like image 57
Pablo Matias Gomez Avatar answered Jan 07 '23 06:01

Pablo Matias Gomez