How to separate a List by a condition using Java 8 streams
data-structures, java, java-8, java-stream
Solution
Here is an example of how you could separate elements (numbers) of this list in even and odd numbers:
List<Integer> myList = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
Map<Boolean, List<Integer>> evenAndOdds = myList.stream()
.collect(partitioningBy(i -> i % 2 == 0));
You would get lists of even/odd numbers like this (either list may be empty):
List<Integer> even = evenAndOdds.get(true);
List<Integer> odd = evenAndOdds.get(false);
You could pass any lambda with required logic in `partitioningBy`.
Problem
Consider the following code: ``` List<Integer> odd = new ArrayList<Integer>(); List<Integer> even = null; List<Integer> myList = Arrays.asList(1,2,3,4,5,6,7,8,9,10); even = myList.stream() .filter(item -> { if(item%2 == 0) { return true;} else { odd.add(item); return false; } }) .collect(Collectors.toList()); ``` What I am trying to do here is get the even and odd values from a list into separate lists. The stream `filter()` method returns `true` for even items and the stream collector will collect them. For the odd case, the filter will return `false` and the item will never reach the collector. So I am adding such odd numbers in another list I created before under the `else` block. I know this is not an elegant way of working with streams. For example if I use a parallel stream then there will be thread safety issue with the odd list. I cannot run it multiple times with different filters because of performance reasons (should be O(n)). This is just an example for one use-case, the list could contain any object and the lambda inside the filter needs to separate them based on some logic into separate lists. In simple terms: from a list create multiple lists containing items separated based on some criteria. Without streams it would be just to run a for loop and do simple if-else and collect the items based on the conditions.