一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

Java Stream Collectors功能实现做法全面指南

时间:2026-08-10 10:13:50 编辑:袖梨 来源:一聚教程网

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

Java Stream Collectors功能实现方法全面指南

常用收集器

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:数据转换

// 将列表转换为不可变 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, filteringJava 9
teeingJava 12
toUnmodifiableList/Set/MapJava 10

总结

Collectors 提供了强大的数据收集能力:

  1. 基础收集toList, toSet, toMap, joining
  2. 聚合操作counting, summing, averaging, reducing
  3. 分组分区groupingBy, partitioningBy
  4. 高级功能collectingAndThen, teeing, 自定义收集器

热门栏目