Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java8, Is there a filtering collector?

I want to group a collection but I don't want the aggregations to include some values. What's the best solution to do that?

A solution could be a collector filtering(Predicate,Collector) but there is no such collector. Is there any way to do it without implementing your own collector?

IntStream.range(0,100).collect(
    groupingBy(
       i -> i % 3,
       HashMap::new,
       filtering( i -> i % 2 == 0, toSet() )
    )
);
like image 662
Marcin Król Avatar asked Oct 07 '15 20:10

Marcin Król


People also ask

How will you run a filter on a collection?

You can filter Java Collections like List, Set or Map in Java 8 by using the filter() method of the Stream class. You first need to obtain a stream from Collection by calling stream() method and then you can use the filter() method, which takes a Predicate as the only argument.

What is filter java8?

Java stream provides a method filter() to filter stream elements on the basis of given predicate. Suppose you want to get only even elements of your list then you can do this easily with the help of filter method. This method takes predicate as an argument and returns a stream of consisting of resulted elements.


1 Answers

The only other way I'm aware of is to do the filtering beforehand, that is,

 stream.filter(filterPredicate).collect(collector)

That said, it's not clear what you're actually trying to do with your filtering function, which takes three arguments instead of two.

I suspect you are trying to map a function over elements that match a filter, but that's itself a map, which you can do easily enough:

 Collectors.mapping(input -> condition(input) ? function(input) : input, collector)

And making your own collector isn't actually that difficult:

static <T, A, R> Collector<T, A, R> filtering(
    Predicate<? super T> filter, Collector<T, A, R> collector) {
  return Collector.of(
      collector.supplier(),
      (accumulator, input) -> {
         if (filter.test(input)) {
            collector.accumulator().accept(accumulator, input);
         }
      },
      collector.combiner(),
      collector.finisher());
}
like image 115
Louis Wasserman Avatar answered Oct 19 '22 23:10

Louis Wasserman