Java 8 Stream: Filter, process results, then process the exclusions
java, java-8, java-stream
Solution
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.
Problem
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!