partitioningBy() 一行代码按布尔谓词将流分为 true/false 两组,返回含两个固定键的 Map;支持下游收集器定制每组结构,需注意 null 安全,是 groupingBy 的高效特例。
直接用配合布尔表达式,一行代码就能把流分成和两组,结果是,天然隔离、互不干扰。
核心写法:传入一个返回 boolean 的谓词
这是最简用法。谓词返回
的元素进
,返回
的进
:
不需要手动新建两个 list、遍历两次或做 if-else 分流
分组结果是两个独立的
,修改其中一个不会影响另一个
底层自动完成单次遍历,性能高效
示例:按年龄是否满 18 岁分组
之后可直接取用:
→ 成年人列表
→ 未成年人列表
搭配下游收集器,灵活定制每组结构
第二个参数可指定每组内部如何收集,比如转成 Set、统计数量、求和等,两组互不影响:
要两组都去重 →
只关心每组人数 →
,结果是
按姓名拼接字符串 →
注意 null 安全和逻辑边界
谓词里如果可能遇到 null,必须显式处理,否则抛
:
错:
(p 或 name 为 null 就崩)
对:
也可用
提高可读性
和 groupingBy 的关键区别
是
的特例,但有硬性约束:
分类函数必须返回
,不能是其他类型
结果 Map 必然只有两个 key:
和
(哪怕某组为空,key 也存在,对应空 list)
无需担心 key 冲突或分组爆炸,语义更清晰、开销更低
partitioningby()truefalsemap> truemap.get(true)falsemap.get(false)ListMap> grouped = people.stream()
.collect(Collectors.partitioningBy(p -> p.getAge() >= 18)); grouped.get(true)grouped.get(false)partitioningBy(pred, Collectors.toSet())partitioningBy(pred, Collectors.counting())MappartitioningBy(pred, Collectors.mapping(Person::getName, Collectors.joining(", ")))NullPointerExceptionp -> p.getName().startsWith("A")p -> p != null && p.getName() != null && p.getName().startsWith("A")Objects.nonNull()partitioningBygroupingByBooleantruefalse