Collectors.partitioningBy 是 Java Stream 中专用于二分类分组的收集器,根据布尔谓词将元素分为 true 和 false 两组并返回 Map;支持嵌套下游收集器定制每组聚合结果,适用于“是/否”类场景,语义清晰且性能更优。

Collectors.partitioningBy 是 Java Stream 中用于“二分类分组”的专用收集器,它根据一个布尔条件将流中元素分成两组:满足条件的归入 true 键,不满足的归入 false 键,返回 Map<boolean list>></boolean>。
基础用法:按布尔谓词切分数据
最常用场景是把集合按某个条件一分为二。比如将整数列表分为正数和非正数:
List<Integer> numbers = Arrays.asList(-2, -1, 0, 1, 2, 3);
Map<Boolean, List<Integer>> partitioned = numbers.stream()
.collect(Collectors.partitioningBy(x -> x > 0));
// 结果:{false=[-2, -1, 0], true=[1, 2, 3]}
- 谓词(Predicate)必须返回
boolean,不能为null - 结果 Map 固定只有两个键:
true和false,不会多也不会少 - 即使某组为空,对应键仍存在,值为空列表(不是
null)
进阶用法:嵌套收集器定制分组内容
第二个参数可传入任意下游收集器,控制每组内部如何组织。例如,不要 List,而要每组的总和:
Map<Boolean, Integer> sumBySign = numbers.stream()
.collect(Collectors.partitioningBy(
x -> x >= 0,
Collectors.summingInt(Integer::intValue)
));
// 结果:{false=-3, true=6}
- 下游收集器可以是
Collectors.counting()、Collectors.maxBy(Comparator)等 - 若用
Collectors.toSet(),结果类型变为Map<boolean set>></boolean> - 注意下游收集器的泛型需与流元素类型兼容
常见误区与注意事项
容易忽略的细节会影响结果正确性:
立即学习“Java免费学习笔记(深入)”;
- 谓词逻辑要覆盖全部情况——比如用
x > 0区分正负数,0 就会进入false组,若想把 0 单独处理,需改用partitioningBy+ 多条件判断或换用groupingBy - 不能直接对
null元素调用谓词,需提前过滤或判空,否则抛NullPointerException - 分区结果 Map 是
HashMap,不保证true/false的插入顺序(但通常false在前、true在后)
对比 groupingBy:何时选 partitioningBy?
两者都分组,但语义不同:
-
groupingBy(classifier)适用于多分类(如按城市、按年级、按状态码),返回Map<k list>></k> -
partitioningBy(predicate)专为“是/否”、“有/无”、“通过/未通过”这类二元判断设计,语义更清晰、性能略优(内部做了优化) - 如果分类逻辑本质是布尔判断,优先用
partitioningBy,代码更易读且不易出错


















