Collectors.partitioningBy 是 Java 8 中用于二元分区的专用收集器,根据 Predicate 将流元素分为 true/false 两组并返回 Map;支持嵌套收集器定制结果类型,要求 predicate 显式处理 null,不保证顺序,默认使用 HashMap。

Collectors.partitioningBy 是 Java 8 Stream API 中用于将数据分成 两个组 的专用收集器,本质是基于布尔条件做二分:满足条件的进 true 组,不满足的进 false 组。它返回一个 Map<boolean list>></boolean>,结构简单、语义清晰,适合“是/否”“有/无”“启用/禁用”这类二元分类场景。
基础用法:按布尔表达式分区
最常见的是传入一个 Predicate,对每个元素判断真假:
List<String> words = Arrays.asList("apple", "cat", "dog", "banana");
Map<Boolean, List<String>> partitioned = words.stream()
.collect(Collectors.partitioningBy(s -> s.length() > 3));
// 结果:{false=[cat, dog], true=[apple, banana]}
注意:partitioningBy 总是生成包含 true 和 false 两个 key 的 map,哪怕某组为空(对应空列表)。
进阶用法:嵌套收集器定制分组内容
第二个参数可传入任意 Collector,用来改变子集合的类型或结构。例如转成 Set、统计数量、或进一步映射:
立即学习“Java免费学习笔记(深入)”;
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
- 转为
Set去重:partitioningBy(pred, Collectors.toSet()) - 只统计每组数量:
partitioningBy(pred, Collectors.counting())→ 返回Map<boolean long></boolean> - 提取首字母并收集为 List:
partitioningBy(s -> s.startsWith("a"), mapping(String::substring, toList()))
实用技巧与注意事项
分区结果是 HashMap,不保证顺序;如需有序,可用 Collectors.partitioningBy(..., LinkedHashMap::new, ...) 指定 map 工厂。
和 groupingBy 的区别要清楚:后者支持任意键类型(如按年龄分组),而 partitioningBy 强制二值,性能略优且意图更明确。
不能直接处理 null 元素——若流中可能含 null,需提前过滤或在 predicate 中显式判空,否则会抛 NullPointerException。
真实场景示例:用户状态分区
比如区分活跃用户和非活跃用户:
record User(String name, boolean isActive) {}
List<User> users = List.of(
new User("Alice", true),
new User("Bob", false),
new User("Charlie", true)
);
Map<Boolean, List<String>> namesByActive = users.stream()
.collect(Collectors.partitioningBy(
User::isActive,
mapping(User::name, toList())
));
// {false=[Bob], true=[Alice, Charlie]}
这里结合 mapping 提前提取姓名,避免后续遍历再取字段。

















