Collectors partitioningBy() method in Java
In this post, we will show we how to use the Collectors.partitioningBy() method in Java to partition a stream of data according to a given predicate.
1. What is the Collectors.partitioningBy() Method?
The Collectors.partitioningBy() method is a static method that returns a Collector that partitions the input elements according to a Predicate, and organizes them into a Map<Boolean, List<T>>. The syntax is as follows:
|
1 |
public static <T> Collector<T, ?, Map<Boolean, List<T>>> partitioningBy(Predicate<? super T> predicate) |
Here, T is the type of the input elements. The predicate parameter is used to test each element of the stream and assign it to one of the two groups: true or false. The map returned by the collector has two keys: true and false, and the corresponding values are lists that contain the elements that belong to each group.
This method is useful to partition a stream of data into two groups based on a certain condition. For example, we may have a stream of numbers and we want to split them into even and odd numbers. Or we may have a stream of products and we want to split them into cheap and expensive products. The Collectors.partitioningBy() method can help us with this task.
2. How to use the Collectors.partitioningBy() Method?
Let’s see some examples of how to use the Collectors.partitioningBy() method in Java with different types of streams and predicates.
Example 1: Partitioning a Stream of integers by odd and even numbers
Suppose we have a stream of integers and we want to partition them into even and odd numbers. We can use the Collectors.partitioningBy() method with a predicate that checks if an element is divisible by 2:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; class Main { private static final int PASS_THRESHOLD = 40; public static void main(String[] args) { Stream<Integer> numbers = Stream.of(1, 2, 3, 4, 5); Map<Boolean, List<Integer>> map = numbers.collect( Collectors.partitioningBy(n -> n % 2 == 0)); System.out.println(map); // {false=[1, 3, 5], true=[2, 4]} System.out.println("Even numbers: " + map.get(true)); // [2, 4] System.out.println("Odd numbers: " + map.get(false)); // [1, 3, 5] } } |
Example 2: Partitioning a Stream of strings by length
Suppose we have a stream of strings and we want to partition them into short and long words based on their length. We can use the Collectors.partitioningBy() method with a predicate that checks if an element has more than four characters:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; class Main { public static void main(String[] args) { Stream<String> words = Stream.of("apple", "boy", "cat", "dog", "elephant"); Map<Boolean, List<String>> map = words.collect( Collectors.partitioningBy(w -> w.length() > 4)); System.out.println("Partition 1: " + map.get(true)); // [apple, elephant] System.out.println("Partition 2: " + map.get(false)); // [boy, cat, dog] } } |
Example 3: Partitioning a Stream of objects by property
Suppose we have a stream of objects that represent students and we want to partition them into passed and failed students based on their marks. We can use the Collectors.partitioningBy() method with a predicate that checks if a student has a marks more than or equal to a threshold:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; class Student { private String name; private int marks; Student(String name, Integer marks) { this.name = name; this.marks = marks; } public String getName() { return name; } public int getMarks() { return marks; } @Override public String toString() { return getName(); } } class Main { private static final int PASS_THRESHOLD = 40; public static void main(String[] args) { List<Student> students = Arrays.asList(new Student("Tom", 90), new Student("Lisa", 98), new Student("John", 85), new Student("Joe", 80), new Student("Jason", 35)); Map<Boolean, List<Student>> passingFailing = students.stream() .collect(Collectors.partitioningBy(s -> s.getMarks() >= PASS_THRESHOLD)); System.out.println("Passed: " + passingFailing.get(true)); // [Tom, Lisa, John, Joe] System.out.println("Failed: " + passingFailing.get(false)); // [Jason] } } |
3. Advantages and Disadvantages of Collectors.partitioningBy() method
Partitioning streams is a common and useful task in Java, as it allows us to split data into groups based on certain criteria. Some of the advantages of the Collectors.partitioningBy() method are:
- It takes only one method call to partition a stream of data according to a given condition.
- It can work with any type of stream and predicate, as long as they are compatible.
- It does not modify the original stream or its elements, but returns a new map as the result.
The Collectors.partitioningBy() method also has some disadvantages that we should be aware of before using it:
- It can only partition a stream into only two groups. If you need more than two groups, we may need to use other methods, such as
groupingBy()ormapping(). - It creates a new map and two new lists for each partitioning operation, which may consume more memory or time than necessary.
That’s all about the Collectors.partitioningBy() method in Java.
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)