groupingby 与 mapping 结合可实现按字段分组并投影提取,如将员工列表按部门分组后只保留姓名列表;mapping 作为下游收集器,需配合 groupingby 等使用,其第一个参数为任意 function。

在 Java Stream API 中,groupingBy 与 mapping 结合使用,可以实现「按某字段分组 + 对每组内元素做字段提取(投影)」的效果,常用于把 List
核心组合:groupingBy + mapping
Collectors.mapping 是一个下游收集器(downstream collector),必须配合其他收集器(如 groupingBy、toMap)使用。它负责对每个流元素先做一次转换,再交给下游收集器处理。
典型签名:
Collectors.groupingBy(keyMapper,Collectors.mapping(valueMapper,Collectors.toList()))
常见用法示例:按部门分组,只取员工姓名列表
假设有员工类:
record Employee(String name, String dept, int salary) {}
要得到 Map<string list>></string>(部门 → 姓名列表):
List<employee> employees = List.of(</employee>new Employee("张三", "研发部", 15000),new Employee("李四", "研发部", 18000),new Employee("王五", "市场部", 12000));Map<string list>> deptToNames = employees.stream()</string>.collect(Collectors.groupingBy(Employee::dept,Collectors.mapping(Employee::name, Collectors.toList())));
结果:{"研发部": ["张三", "李四"], "市场部": ["王五"]}
支持更复杂的投影转换
mapping 的第一个参数是任意 Function super T, ? extends U>,不局限于 getter 方法:
- 转为大写:
e -> e.name().toUpperCase() - 拼接字符串:
e -> e.name() + "(" + e.salary() + ")" - 条件映射:
e -> e.salary() > 15000 ? "高薪" : "普通" - 提取嵌套属性:
e -> e.profile().getLevel()(假设 profile 非 null)
注意事项与避坑点
-
mapping不会自动过滤 null —— 若 valueMapper 返回 null,且下游是toList(),null 会被加入列表;需提前判空或用filter预处理 - 若想得到
Set而非List,把Collectors.toList()换成Collectors.toSet() - 若分组后只需单个值(如每组取最高薪资),应改用
collectingAndThen或maxBy等,而非mapping+toList - 嵌套使用时注意泛型推断,必要时显式指定类型,避免编译错误
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











