Java 8 Stream: filters, processes results, then handles exceptions

In Java 8 threads, I know how to filter a collection based on a predicate, and handle elements for which the predicate was true. I am wondering if the predicate divides the collection into two groups, is it possible to filter through the predicate through the API, process the filtered results, and then immediately chain to a call to process all elements excluded by the filter

For example, 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 do I just need to execute the forEach process for the filtered elements, and then call stream() and filter() in the source list to process the remaining elements?

Thanks!

+5
source share
2 answers

See Collectors.partitioningBy , which takes a predicate as an argument. You must use Stream.collect to use it.

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

Note that Collectors.partitioningBy has an overloaded version that takes a second argument, which is a top-down collector that you can use if you want each section to be put together in something other than a list.

In your example, you can use it as follows:

 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 point, taken from a comment posted by @Holger in a related question:

Collectors.partitioningBy will always have a result for true and false in Map , that is, in an empty list, if not a single item falls into this group, and not null .

This feature was added to jdk9 docs as an API note (again, this was observed by user @Holger):

If the section has no elements, its value in the resulting map will be empty.

+8
source

There is no access operation for excluded items in the Stream interface. However, you can implement a more complex predicate:

 intList.stream() .filter(i -> { if (i < 3) return true; else { // Process excluded item i return false; } }).forEach(/* Process included item. */) 

But you must be careful that the predicate is non-interfering and stateless.

+1
source

All Articles