collectors.groupingby是java stream api中用于按指定规则分组的核心工具,支持简单分组、下游收集器定制(如counting、toset、summingint等)、多级嵌套分组,并需手动处理null键和空分组。

Java 的 Stream API 中,Collectors.groupingBy 是最常用、最灵活的分组工具,它能把流中元素按指定规则分类,生成 Map<k list>></k>(默认)或更复杂的结构,比如带统计、聚合、嵌套分组等。
基础用法:按字段简单分组
最常见场景是按对象某个属性分组,例如把学生列表按年级分组:
List<student> students = Arrays.asList(
new Student("张三", "高一"),
new Student("李四", "高二"),
new Student("王五", "高一")
);
Map<string list>> byGrade = students.stream()
.collect(Collectors.groupingBy(Student::getGrade));
// 结果:{"高一": [张三, 王五], "高二": [李四]}
</string></student>
注意:groupingBy 第一个参数是分类函数(Function<t></t>),返回每个元素对应的分组键。
进阶用法:自定义下游收集器(替代默认 List)
默认返回 Map<k list>></k>,但常需其他形式,比如统计数量、求和、转 Set 或嵌套分组。这时用第二个参数传入下游收集器(downstream collector):
-
统计每组数量:
Collectors.counting() -
提取某字段转 Set:
Collectors.mapping(Student::getName, Collectors.toSet()) -
求某字段总和:
Collectors.summingInt(Student::getScore) -
获取每组最大值:
Collectors.maxBy(Comparator.comparing(Student::getScore))
示例:按年级分组并统计人数
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
Map<string long> countByGrade = students.stream()
.collect(Collectors.groupingBy(Student::getGrade, Collectors.counting()));
// {"高一": 2, "高二": 1}
</string>
多级分组:嵌套 groupingBy
用 groupingBy 作为下游收集器,可实现“先按年级,再按班级”这类两级分组:
Map<string map list>>> byGradeAndClass = students.stream()
.collect(Collectors.groupingBy(
Student::getGrade,
Collectors.groupingBy(Student::getClassName)
));
// {"高一": {"1班": [...], "2班": [...]}, "高二": {...}}
</string>
支持任意深度嵌套,但建议控制在两层以内,保证可读性与维护性。
处理 null 值与空分组
若分类函数可能返回 null,默认会抛 NullPointerException。解决方式有二:
- 提前过滤掉 null:
stream().filter(s -> s.getGrade() != null).collect(...) - 用
Collectors.groupingBy(keyMapper, LinkedHashMap::new, downstream)自定义 map 类型,并配合Objects.toString(key, "unknown")统一处理 null 键
另外,如果想让结果包含“零值分组”(如某年级没人,仍显示该年级 → 0),需先构造完整键集合,再用 Map.computeIfAbsent 补全,groupingBy 本身不主动补空组。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










