java stream api的collectors.groupingby支持多层级分组,本质是嵌套使用groupingby,每层对应一个分类维度,最终生成嵌套map结构;单层按部门分组得map,两层嵌套(如部门→职位)得map,三层及以上可继续递进嵌套;每层可搭配不同下游收集器(如counting、averagingdouble)优化结果结构。

Java Stream API 的 Collectors.groupingBy 支持多层级分组,本质是嵌套使用 groupingBy,每层对应一个分类维度,最终生成嵌套的 Map 结构。
基础单层分组
最常见用法是按单一字段分组,例如按部门划分员工列表:
Map<string list>> byDept = employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment));</string>
结果是一个 Map<string list>></string>,键为部门名,值为该部门员工列表。
两层嵌套分组(常用)
先按一级字段分组,再对每个子组按二级字段进一步分组。例如:先按部门,再按职位:
- 外层 groupingBy 返回
Map<string map list>>></string> - 内层 groupingBy 作为下游收集器传入,写在第二个参数位置
Map<string map list>>> byDeptAndRole = employees.stream()
.collect(Collectors.groupingBy(
Employee::getDepartment,
Collectors.groupingBy(Employee::getRole)
));</string>
访问方式如:byDeptAndRole.get("Tech").get("Engineer") 获取技术部工程师列表。
三层及以上分组(递进嵌套)
继续在内层 groupingBy 中嵌套新的 groupingBy 即可。例如:部门 → 职位 → 年龄段(按 10 年分段):
Map<string map list>>>> result = employees.stream()
.collect(Collectors.groupingBy(
Employee::getDepartment,
Collectors.groupingBy(
Employee::getRole,
Collectors.groupingBy(e -> e.getAge() / 10 * 10) // 如 25→20,37→30
)
));</string>
注意:每增加一层,返回类型就多一层 Map 嵌套,读取时需逐级调用 get。
结合下游收集器优化结构
默认每层都生成 List,但可替换为其他收集器以减少内存或满足业务需求:
- 用
Collectors.counting()统计数量而非保存对象 - 用
Collectors.summingInt(e -> e.getSalary())汇总薪资 - 用
Collectors.mapping(..., Collectors.toList())提前投影字段
例如:部门 → 职位 → 各职位平均薪资:
Map<string map double>> avgSalaryByDeptAndRole = employees.stream()
.collect(Collectors.groupingBy(
Employee::getDepartment,
Collectors.groupingBy(
Employee::getRole,
Collectors.averagingDouble(Employee::getSalary)
)
));</string>
多层级 groupingBy 的核心是“层层嵌套、逐级细化”,关键在于理清分组维度顺序和下游收集器的组合方式,不复杂但容易忽略类型推导和空值处理。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











