Java Stream操作列表注入字符串仅重复键首行生效问题咨询
Java Stream toMap 合并重复key并注入公共字段解决方案
问题根因
- 合并函数触发限制:
Collectors.toMap的第三个参数(合并冲突处理函数)仅在出现重复key时才会执行,无冲突的key会直接使用第二个参数(value映射器)的返回结果。你原有代码用Function.identity()直接返回原始Person对象,原始对象的lastName字段未赋值,因此非重复的John条目lastName为null。 - 合并逻辑缺失:原有合并函数中amount未做累加,仅取了第一个冲突条目的数值,无法得到两条合并后的总数值2。
- key规则不匹配需求:如果需要合并大小写不同的同名条目(如Kelvin和kelvin),当前
f.getCode() + f.getName()的规则会因为code不同、姓名大小写不同生成不同的key,不会触发合并。 - 代码笔误:原有代码中
String lastName = "Alvin"末尾缺少分号,s.getName缺少方法调用括号。
修复后代码
String lastName = "Alvin"; Map<String, Person> map = list.stream().collect(Collectors.toMap( // 按忽略大小写的姓名作为合并key,可根据实际业务调整 f -> f.getName().toLowerCase(), // value生成阶段就注入lastName,确保所有条目都有值 f -> new Person(f.getCode(), f.getName(), f.getAmount(), lastName), // 冲突合并:累加amount,保留第一个条目的code和姓名 (existPerson, newPerson) -> new Person( existPerson.getCode(), existPerson.getName(), existPerson.getAmount() + newPerson.getAmount(), lastName ) )); // 如果需要转为List输出 List<Person> result = new ArrayList<>(map.values());
效果验证
处理后所有条目无论是否触发合并,lastName都为Alvin,重复key条目的amount会自动累加,和你的预期输出完全一致。
内容的提问来源于stack exchange,提问作者Alvin
相关产品推荐
相关产品推荐

