Collectors.partitioningBy根据布尔条件将流元素分为两组,适用于二元分类场景。例如按年龄区分成年与未成年用户,支持结合下游收集器统计数量或提取属性,提升代码可读性。

在Java 8引入的Stream API中,Collectors.partitioningBy 是一个非常实用的收集器,它可以根据一个布尔条件将集合元素划分为两个分区:满足条件的归为一组(key为true),不满足的归为另一组(key为false)。这种操作在需要对数据进行二分分类时特别高效。
partitioningBy的基本用法
该方法接收一个Predicate函数式接口作为参数,返回一个Map
假设我们有一个用户列表,想把成年用户和未成年用户分开:
Listusers = Arrays.asList( new User("Alice", 25), new User("Bob", 17), new User("Charlie", 30), new User("Diana", 16) ); Map > partitionedByAge = users.stream() .collect(Collectors.partitioningBy(user -> user.getAge() >= 18)); System.out.println("成年人: " + partitionedByAge.get(true)); System.out.println("未成年人: " + partitionedByAge.get(false));
输出结果将是:
立即学习“Java免费学习笔记(深入)”;
成年人: [User{name='Alice', age=25}, User{name='Charlie', age=30}]
未成年人: [User{name='Bob', age=17}, User{name='Diana', age=16}]
结合下游收集器进行高级分区
除了默认生成List外,还可以指定下游收集器来改变分区后的数据结构。例如,只统计每组人数:
MapcountByAgeGroup = users.stream() .collect(Collectors.partitioningBy( user -> user.getAge() >= 18, Collectors.counting() )); System.out.println("成年组人数: " + countByAgeGroup.get(true)); // 输出 2 System.out.println("未成年组人数: " + countByAgeGroup.get(false)); // 输出 2
也可以将名字提取成集合:
Map> namesPartitioned = users.stream() .collect(Collectors.partitioningBy( user -> user.getAge() >= 18, Collectors.mapping(User::getName, Collectors.toList()) ));
实际应用场景建议
使用 partitioningBy 适合处理非此即彼的二元分类问题。比如:
- 区分通过/未通过考试的学生
- 分离启用或禁用状态的配置项
- 按奇偶数拆分数字列表
- 判断字符串是否为空或符合格式
注意:如果分类标准多于两种,应考虑使用 Collectors.groupingBy 而不是多次调用partitioningBy。
基本上就这些。合理利用partitioningBy能让代码更清晰,减少手动遍历和if-else判断,提升可读性和维护性。










