Java 8 Stream: Filter, process results, then process the exclusions

alowellj :

In Java 8's Streams, I know how to filter a collection based on a predicate, and process the items for which the predicate was true. What I'm wondering is, if the predicate divides the collection into only two groups, is it possible through the API to filter based on the predicate, process the filtered results, then immediately chain on a call to process all elements excluded by the filter?

For instance, consider the following List:

List<Integer> intList = Arrays.asList(1,2,3,4);

Is it possible to do:

intList.stream()
    .filter(lessThanThree -> lessThanThree < 3)
    .forEach(/* process */)
    .exclusions(/* process exclusions */); //<-- obviously sudocode

Or would I have to just do the forEach process for the filtered items and then call stream() and filter() on the original list to then process the remaining items?

Thanks!

Federico Peralta Schaffner :

Take a look at Collectors.partitioningBy, which receives a predicate as an argument. You must use Stream.collect to use it.

The result is a map with only two Boolean entries: for the true key, you have a List containing the elements of the stream that matched the predicate, while for the false key, you have a List containing the elements that didn't match.

Note that Collectors.partitioningBy has an overloaded version that accepts a second argument, which is a downstream collector you can use if you want each partition to be collected to something different than a list.

In your example, you could use it this way:

Map<Boolean, List<Integer>> partition = intList.stream()
    .collect(Collectors.partitioningBy(i -> i < 3));

List<Integer> lessThan = partition.get(true); // [1, 2]
List<Integer> notLessThan = partition.get(false); // [3, 4]

I would also like to highlight an important observation, taken from a comment added by user @Holger in the linked question:

Collectors.partitioningBy will always have a result for true and false in the Map, i.e. an empty list if no element fell into that group, rather than null.

This particularity has been added to jdk9 docs as an API Note (again, this was observed by user @Holger):

If a partition has no elements, its value in the result Map will be an empty List.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=435172&siteId=1