1

I am studying Java8 and want to perform following operations using stream API in Java8.

Input: List of (1,2,3,4,5,6,7,8,9)

Output: Odd List - (1,3,5,7,9) Even List - (2,4,6,8)

I can do this operation in single for loop in traditional java like

List<Integer> ints = Arrays.asList(3,4,2,5,6,7,4,5);
List<Integer> oddList = new ArrayList<>();
List<Integer> evenList = new ArrayList<>();

for (Integer i : ints) {
    if (i % 2 == 0) {
        evenList.add(i);
    } else {
        oddList.add(i);
    }
}

I know a way to do this in Java8 style as follows -

List<Integer> evens = ints.stream().filter(i -> i % 2 == 0).collect(Collectors.toList());
List<Integer> odds = ints.stream().filter(i -> i % 2 == 1).collect(Collectors.toList());

But here the problem is that I am iterating the ints twice instead of once. Is there a way that this can be done without iterating twice in streams?

Harish
  • 169
  • 1
  • 2
  • 7

1 Answers1

5

Use the partitioningBy collector. It collects the stream into a map, which has 2 lists. One list contains elements that satisfy the predicate, the other contains those that don't.

Map<Boolean, List<Integer>> partitions = ints.stream()
    .collect(Collectors.partitioningBy(x -> x % 2 == 0));
List<Integer> evens = partitions.get(true);
List<Integer> odds = partitions.get(false);
Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • Just curious. What if we need a three sublists? like oddList, evenList and negativeList? – Harish Feb 10 '21 at 03:21
  • Create an enum with a value for each list, and write a function which returns an enum, replacing the function returning a boolean above. – tgdavies Feb 10 '21 at 03:22
  • 2
    If they are disjoint groups (i.e. negatives are neither odd nor even), you can use `groupingBy`. @Harish – Sweeper Feb 10 '21 at 03:26