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










