Collectors 是 Java Stream API 中最强大的工具之一,提供了丰富的收集器实现,用于将流中的元素聚合为各种结果。

List<String> list = stream.collect(Collectors.toList());
用途:将流元素收集到 List 中
返回:ArrayList(非线程安全)
Set<Integer> set = stream.collect(Collectors.toSet());
用途:将流元素收集到 Set 中(自动去重)
返回:HashSet
Map<String, Integer> map = stream.collect( Collectors.toMap( Function.identity(), // key 映射 Function.identity() // value 映射 ));
用途:将流元素收集到 Map 中
注意:需要处理 key 冲突,可通过第三个参数指定合并策略
String result = stream.collect(Collectors.joining());// 带分隔符String result = stream.collect(Collectors.joining(", "));// 带分隔符、前缀、后缀String result = stream.collect(Collectors.joining(", ", "[", "]"));用途:将字符串流连接成单个字符串
Long count = stream.collect(Collectors.counting());
用途:统计流中元素数量
也可用:stream.count()(更简洁)
IntSummaryStatistics stats = stream.collect( Collectors.summarizingInt(Integer::intValue));// 获取: count, sum, min, max, average
用途:获取数值流的统计摘要信息
// 基础分组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()) ));
用途:按分类函数对元素分组
Map<Boolean, List<Integer>> partitioned = stream.collect( Collectors.partitioningBy(n -> n % 2 == 0));// 结果: {false=[奇数], true=[偶数]}用途:按谓词将元素分为两组(true/false)
// 基础归约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 ));
用途:通过二元运算将元素归约为单个值
Integer sum = stream.collect(Collectors.summingInt(Integer::intValue));
用途:对数值流求和
Double average = stream.collect(Collectors.averagingInt(Integer::intValue));
用途:计算数值流的平均值
Optional<Integer> max = stream.collect(Collectors.maxBy(Integer::compareTo));Optional<Integer> min = stream.collect(Collectors.minBy(Integer::compareTo));
用途:获取流中的最大/最小元素
List<String> unmodifiableList = stream.collect( Collectors.collectingAndThen( Collectors.toList(), Collections::unmodifiableList ));
用途:收集后对结果进行转换
Set<String> names = stream.collect( Collectors.mapping( Employee::getName, Collectors.toSet() ));
用途:先映射再收集
Set<String> allSkills = stream.collect( Collectors.flatMapping( emp -> emp.getSkills().stream(), Collectors.toSet() ));
用途:扁平化映射后收集
List<Employee> senior = stream.collect( Collectors.filtering( emp -> emp.getAge() > 50, Collectors.toList() ));
用途:过滤后再收集
Collector<String, ?, String> customCollector = Collector.of( StringBuilder::new, // supplier: 创建可变容器 StringBuilder::append, // accumulator: 累加元素 StringBuilder::append, // combiner: 合并容器 StringBuilder::toString // finisher: 转换结果);
用途:创建完全自定义的收集器
// 同时进行多种收集Map<String, Object> result = stream.collect( Collectors.teeing( Collectors.counting(), Collectors.summingDouble(Double::doubleValue), (count, sum) -> Map.of("count", count, "sum", sum) ));用途:在一个操作中执行多个收集器(Java 12+)
// 按部门分组,收集员工姓名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) ));
// 将列表转换为不可变 MapMap<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, joiningcounting, summing, averaging, reducinggroupingBy, partitioningBycollectingAndThen, teeing, 自定义收集器