Learnitweb

Collectors partitioningBy() method in Java

1. Introduction

In Java, the Collectors class provides various methods to collect data from streams. One of the most powerful and frequently used methods is Collectors.partitioningBy(). This method is used to partition a stream of elements into two groups based on a given predicate. It returns a Map with Boolean keys (true and false) and lists of elements as values.

2. Syntax

public static<T> Collector<T, ?, Map<Boolean, List<T>>> partitioningBy​(Predicate<? super T> predicate)Returns a Collector that divides the input elements based on a Predicate, storing them in a Map<Boolean, List<T>>. This resulting Map will always have entries for both false and true keys. The type, mutability, serializability, and thread-safety of the returned Map and List are not guaranteed.
public static<T,D,A> Collector<T,?,Map<Boolean,D>> partitioningBy​(Predicate<? super T> predicate, Collector<? super T,A,D> downstream)Returns a Collector that divides the input elements based on a Predicate, processes the values in each partition using another Collector, and stores the results in a Map, where the values are the outcomes of the downstream processing.
The resulting Map will always include entries for both false and true keys. The type, mutability, serializability, and thread-safety of the returned Map are not assured.
  • T – the type of the input elements
  • A – the intermediate accumulation type of the downstream collector
  • D – the result type of the downstream reduction

3. Example 1

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class PartitionByExample {
    public static void main(String[] args) throws InterruptedException {
        // List of integers
        List<Integer> list = List.of(1,2,3,4,5,6,7,8,9,10, 11);
        
        // partition by predicate, where numbers are greater than 5
        Map<Boolean, List<Integer>> result = list.stream().collect(Collectors.partitioningBy(num -> num > 5));
        
        //print the result
        System.out.println(result);
    }
}

Output

{false=[1, 2, 3, 4, 5], true=[6, 7, 8, 9, 10, 11]}

4. Example 2

In this example, the downstream collector accumulates the counting result.

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class PartitionByExample {
    public static void main(String[] args) throws InterruptedException {
        // List of integers
        List<Integer> list = List.of(1,2,3,4,5,6,7,8,9,10, 11);

        // partition by predicate, where numbers are greater than 5
        Map<Boolean, Long> result = list.stream().collect(Collectors.partitioningBy(num -> num > 5, Collectors.counting()));

        //print the result
        System.out.println(result);
    }
}

Output

{false=5, true=6}

5. Example 3

In this example, we’ll find even and odd numbers in the list.

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class PartitioningExample {
    public static void main(String[] args) {
        List<Integer> numbers = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10).collect(Collectors.toList());

        Map<Boolean, List<Integer>> partitioned = numbers.stream()
                .collect(Collectors.partitioningBy(n -> n % 2 == 0));

        System.out.println("Even numbers: " + partitioned.get(true));
        System.out.println("Odd numbers: " + partitioned.get(false));
    }
}

Output

Even numbers: [2, 4, 6, 8, 10]
Odd numbers: [1, 3, 5, 7, 9]

6. Example 4

In this example, we’ll partition a list of strings into those with length greater than 3 and those with length 3 or less. Additionally, we’ll count the number of elements in each partition using the downstream collector.

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class PartitioningWithDownstreamExample {
    public static void main(String[] args) {
        List<String> words = Stream.of("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten")
                .collect(Collectors.toList());

        Map<Boolean, Long> partitioned = words.stream()
                .collect(Collectors.partitioningBy(word -> word.length() > 3, Collectors.counting()));

        System.out.println("Words with length > 3: " + partitioned.get(true));
        System.out.println("Words with length <= 3: " + partitioned.get(false));
    }
}

Output

Words with length > 3: 6
Words with length <= 3: 4

7. Conclusion

The Collectors.partitioningBy() method in Java is a versatile tool for partitioning streams of data into two groups based on a predicate. It is particularly useful when you need to separate elements into two categories and perform additional processing on each group. By understanding its syntax, usage, and best practices, you can effectively leverage this method in your Java applications.