Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to separate a List by a condition using Java 8 streams

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.

like image 848
Roy Avatar asked May 03 '17 17:05

Roy


People also ask

How do I print a List of objects from a stream?

There are 3 ways to print the elements of a Stream in Java: forEach() println() with collect() peek()

What are the methods in streams in Java 8?

With Java 8, Collection interface has two methods to generate a Stream. stream() − Returns a sequential stream considering collection as its source. parallelStream() − Returns a parallel Stream considering collection as its source.


1 Answers

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.

like image 76
Manos Nikolaidis Avatar answered Oct 25 '22 14:10

Manos Nikolaidis