Java Stream Collectors 功能全面指南
Collectors 是 Java Stream API 中最强大的工具之一,提供了丰富的收集器实现,用于将流中的元素聚合为各种结果。
常用收集器
1. toList() – 收集为列表
List<String> list = stream.collect(Collectors.toList());
用途:将流元素收集到 List 中
返回:ArrayList(非线程安全)
2. toSet() – 收集为集合
Set<Integer> set = stream.collect(Collectors.toSet());
用途:将流元素收集到 Set 中(自动去重)
返回:HashSet
3. toMap() – 收集为映射
Map<String, Integer> map = stream.collect(
Collectors.toMap(
Function.identity(), // key 映射
Function.identity() // value 映射
)
);
用途:将流元素收集到 Map 中
注意:需要处理 key 冲突,可通过第三个参数指定合并策略
4. joining() – 字符串连接
String result = stream.collect(Collectors.joining());
// 带分隔符
String result = stream.collect(Collectors.joining(", "));
// 带分隔符、前缀、后缀
String result = stream.collect(Collectors.joining(", ", "[", "]"));
用途:将字符串流连接成单个字符串
5. counting() – 计数
Long count = stream.collect(Collectors.counting());
用途:统计流中元素数量
也可用:stream.count()(更简洁)
6. summarizingInt/Long/Double() – 统计摘要
IntSummaryStatistics stats = stream.collect(
Collectors.summarizingInt(Integer::intValue)
);
// 获取: count, sum, min, max, average
用途:获取数值流的统计摘要信息
分组与分区
7. groupingBy() – 分组
// 基础分组
Map<String, List<Employee>> grouped = stream.collect(
Collectors.groupingBy(Employee::getDepartment)
);
// 带下游收集器分组
Map<String, Set<String>> grouped = stream.collect(
Collectors.groupingBy(
Employee::getDepartment,
Collectors.mapping(Employee::getName, Collectors.toSet())
)
);
用途:按分类函数对元素分组
8. partitioningBy() – 分区
Map<Boolean, List<Integer>> partitioned = stream.collect(
Collectors.partitioningBy(n -> n % 2 == 0)
);
// 结果: {false=[奇数], true=[偶数]}
用途:按谓词将元素分为两组(true/false)
归约操作
9. reducing() – 归约
// 基础归约
Optional<Integer> sum = stream.collect(
Collectors.reducing(Integer::sum)
);
// 带初始值归约
Integer sum = stream.collect(
Collectors.reducing(0, Integer::sum)
);
// 带映射和归约
Optional<Integer> sum = stream.collect(
Collectors.reducing(
Employee::getSalary,
Integer::sum
)
);
用途:通过二元运算将元素归约为单个值
10. summingInt/Long/Double() – 求和
Integer sum = stream.collect(Collectors.summingInt(Integer::intValue));
用途:对数值流求和
11. averagingInt/Long/Double() – 求平均值
Double average = stream.collect(Collectors.averagingInt(Integer::intValue));
用途:计算数值流的平均值
极值获取
12. maxBy() / minBy() – 最大/最小值
Optional<Integer> max = stream.collect(Collectors.maxBy(Integer::compareTo));
Optional<Integer> min = stream.collect(Collectors.minBy(Integer::compareTo));
用途:获取流中的最大/最小元素
13. collectingAndThen() – 转换结果
List<String> unmodifiableList = stream.collect(
Collectors.collectingAndThen(
Collectors.toList(),
Collections::unmodifiableList
)
);
用途:收集后对结果进行转换
高级收集器
14. mapping() – 映射收集
Set<String> names = stream.collect(
Collectors.mapping(
Employee::getName,
Collectors.toSet()
)
);
用途:先映射再收集
15. flatMapping() – 扁平映射收集(Java 9+)
Set<String> allSkills = stream.collect(
Collectors.flatMapping(
emp -> emp.getSkills().stream(),
Collectors.toSet()
)
);
用途:扁平化映射后收集
16. filtering() – 过滤收集(Java 9+)
List<Employee> senior = stream.collect(
Collectors.filtering(
emp -> emp.getAge() > 50,
Collectors.toList()
)
);
用途:过滤后再收集
自定义收集器
17. of() – 创建自定义收集器
Collector<String, ?, String> customCollector = Collector.of(
StringBuilder::new, // supplier: 创建可变容器
StringBuilder::append, // accumulator: 累加元素
StringBuilder::append, // combiner: 合并容器
StringBuilder::toString // finisher: 转换结果
);
用途:创建完全自定义的收集器
收集器组合
18. 多重收集器
// 同时进行多种收集
Map<String, Object> result = stream.collect(
Collectors.teeing(
Collectors.counting(),
Collectors.summingDouble(Double::doubleValue),
(count, sum) -> Map.of("count", count, "sum", sum)
)
);
用途:在一个操作中执行多个收集器(Java 12+)
实用示例
示例 1:员工数据处理
// 按部门分组,收集员工姓名
Map<String, List<String>> departmentEmployees = employees.stream()
.collect(Collectors.groupingBy(
Employee::getDepartment,
Collectors.mapping(Employee::getName, Collectors.toList())
));
// 按部门统计薪资
Map<String, Double> departmentSalary = employees.stream()
.collect(Collectors.groupingBy(
Employee::getDepartment,
Collectors.summingDouble(Employee::getSalary)
));
示例 2:数据转换
// 将列表转换为不可变 Map
Map<Integer, Employee> employeeMap = employees.stream()
.collect(Collectors.toUnmodifiableMap(
Employee::getId,
Function.identity()
));
// 字符串拼接
String employeeNames = employees.stream()
.map(Employee::getName)
.collect(Collectors.joining(", "));
注意事项
| toList() 返回可变列表 | 使用 toUnmodifiableList() 获取不可变列表 |
| toMap() key 冲突 | 提供合并函数作为第三个参数 |
| 并发修改异常 | 使用线程安全的收集器或并行流时注意 |
| 空元素处理 | 在收集前过滤或处理空值 |
版本兼容性
| 基础收集器 | Java 8 |
| flatMapping, filtering | Java 9 |
| teeing | Java 12 |
| toUnmodifiableList/Set/Map | Java 10 |
总结
Collectors 提供了强大的数据收集能力:
- 基础收集:toList, toSet, toMap, joining
- 聚合操作:counting, summing, averaging, reducing
- 分组分区:groupingBy, partitioningBy
- 高级功能:collectingAndThen, teeing, 自定义收集器
网硕互联帮助中心




评论前必须登录!
注册