java中collectors.groupingby用于按分类函数对流元素分组,返回map;配合下游收集器可直接统计数量、求和、平均值等;支持多级分组和自定义map实现。

Java 中用 Collectors.groupingBy 对数据分组统计,核心是传入一个分类函数(即“按什么分组”),它会自动将流中元素归入不同 key 的 Map 中。默认返回 Map<k list>></k>,但配合下游收集器(如 Collectors.counting()、Collectors.summingInt() 等)可直接做统计,避免手动遍历。
基础分组:按字段生成 Map>
最常用场景:按对象某个属性分组,得到每个分组的元素列表。
List<person> people = Arrays.asList(
new Person("张三", 25, "北京"),
new Person("李四", 30, "上海"),
new Person("王五", 25, "北京")
);
// 按城市分组
Map<string list>> byCity = people.stream()
.collect(Collectors.groupingBy(Person::getCity));
// 结果:{"北京": [张三, 王五], "上海": [李四]}
</string></person>
分组 + 计数:统计每组数量
用 Collectors.counting() 作为下游收集器,直接得到 Map<k long></k>。
- 注意返回类型是
Long,不是Integer - 适合快速获取各组元素个数,无需后续 size() 调用
Map<string long> countByAge = people.stream()
.collect(Collectors.groupingBy(Person::getAge, Collectors.counting()));
// 结果:{25=2, 30=1}
</string>
分组 + 聚合:求和、平均值、最大值等
用对应下游收集器,可对每组内某字段做聚合计算:
-
Collectors.summingInt(Person::getAge)→Map<string integer></string> -
Collectors.averagingDouble(Person::getAge)→Map<string double></string> -
Collectors.maxBy(Comparator.comparing(Person::getAge))→Map<string optional>></string>
// 按城市统计平均年龄
Map<string double> avgAgeByCity = people.stream()
.collect(Collectors.groupingBy(
Person::getCity,
Collectors.averagingDouble(Person::getAge)
));
// 结果:{"北京"=25.0, "上海"=30.0}
</string>
多级分组与自定义 Map 实现
支持嵌套分组(如先按城市、再按年龄段),也支持指定 Map 类型(如 TreeMap 保证有序):
- 二级分组:传入两个
groupingBy,外层 key 是第一级,内层 value 是第二级 Map - 定制 Map:第三个参数传入
Supplier<m></m>,例如TreeMap::new
// 先按城市分组,再按年龄段(20-29 / 30+)细分
Map<string map list>>> nested = people.stream()
.collect(Collectors.groupingBy(
Person::getCity,
Collectors.groupingBy(p -> p.getAge() orderedCount = people.stream()
.collect(Collectors.groupingBy(
Person::getCity,
TreeMap::new,
Collectors.counting()
));
</string>Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











