Collectors.partitioningBy 是 Java 8 中用于按布尔条件二分分组的专用收集器,返回键为 true/false、值为对应元素列表的 Map;支持下游收集器定制聚合结果,要求 Predicate 空安全,适用于明确的二元分类场景。
Collectors.partitioningBy
是 Java 8 Stream API 中用于将流中元素按布尔条件“二分分组”的专用收集器,结果返回一个
,其中键为
或
,值为满足或不满足谓词的元素列表。
核心用法:传入 Predicate 即可完成二分
它不需要自定义分类函数,只需一个
(即返回 boolean 的函数),自动拆成两组:
:所有使 predicate 返回
的元素
:其余元素(即 predicate 返回
的元素)
示例:按年龄是否大于等于 18 岁分组
支持嵌套收集器:替换默认的 ArrayList
第二个参数可传入任意下游收集器(如
、
等),改变每组的聚合结果类型:
统计人数:
→
提取姓名:
→
求平均年龄:
→
注意 null 安全与逻辑覆盖
predicate 若返回
(如对 null 引用调用方法),会抛出
。建议提前判空或使用安全表达式:
错误写法:
(p 为 null 时崩)
安全写法:
该操作天然覆盖全部元素——每个元素必属
或
组,无遗漏、无第三组。
和 groupingBy 的关键区别
别混淆二者:
:仅限二分,键固定为
,性能略优,语义更明确
:任意多组,键类型由分类函数决定,更通用但稍重
若业务逻辑本质是“是/否”“有/无”“通过/未通过”这类二元判断,优先用
,代码更直观、意图更清晰。
Map> truefalsePredicatemap.get(true)truemap.get(false)falseMap> byAdult = people.stream()
.collect(Collectors.partitioningBy(p -> p.getAge() >= 18)); Collectors.counting()Collectors.mapping()partitioningBy(..., counting())MappartitioningBy(..., mapping(Person::getName, toList()))Map> partitioningBy(..., averagingInt(Person::getAge))MapnullNullPointerExceptionp -> p.getName().startsWith("A")p -> p != null && p.getName() != null && p.getName().startsWith("A")truefalsepartitioningByBooleangroupingBypartitioningBy