partitioningBy
TL;DR
Collectors.partitioningBy()is a specialized version ofgroupingBy.- It takes a Predicate (true/false condition) rather than a Function.
- It always returns a
Map<Boolean, List<T>>containing exactly two entries: one fortrueand one forfalse.
Concept
While groupingBy can split data into an unlimited number of buckets (e.g., grouping by 50 different US states), partitioningBy splits data into exactly two buckets: those that pass a condition, and those that fail it.
Because the resulting map is guaranteed to only have true and false keys, it is slightly more efficient than groupingBy for binary classifications.
Examples
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
class Student {
String name;
int score;
public Student(String n, int s) { name = n; score = s; }
public int getScore() { return score; }
@Override public String toString() { return name; }
}
public class PartitioningByExample {
public static void main(String[] args) {
List<Student> students = Arrays.asList(
new Student("Alice", 85),
new Student("Bob", 40),
new Student("Charlie", 90),
new Student("David", 30)
);
// Partition students into Pass (>= 50) and Fail (< 50)
Map<Boolean, List<Student>> partitioned = students.stream()
.collect(Collectors.partitioningBy(s -> s.getScore() >= 50));
System.out.println("Passed (True): " + partitioned.get(true));
// Passed (True): [Alice, Charlie]
System.out.println("Failed (False): " + partitioned.get(false));
// Failed (False): [Bob, David]
// You can also use downstream collectors with partitioningBy!
// E.g., getting the average score of passing students vs failing students.
Map<Boolean, Double> avgScores = students.stream()
.collect(Collectors.partitioningBy(
s -> s.getScore() >= 50,
Collectors.averagingInt(Student::getScore)
));
System.out.println(avgScores); // {false=35.0, true=87.5}
}
}
Interview Questions
Q: What happens in partitioningBy if no elements match the true condition?
A: The resulting Map will still contain the true key, but its value will be an empty List. The same applies to the false key. partitioningBy guarantees that both true and false keys exist in the returned map, ensuring you don’t get a NullPointerException when calling .get(true).
Q: When should you use partitioningBy vs groupingBy?
A: If your classification logic returns a boolean (e.g., isAdult, isActive, hasPassed), always use partitioningBy(Predicate). If your classification logic returns a String, Enum, or Object (e.g., getDepartment, getRole), use groupingBy(Function).