如何将嵌套列表转为以B类id为键的Map<Integer, List<A>>
问题解决:将List转换为Map<Integer, List>
现有类结构
public static class A { private List<B> classBList; // constructor, getters, etc. } public static class B { private int id; private String name; // constructor, getters, etc. }
需求说明
需要将输入的List<A>转换为Map<Integer, List<A>>:
- 键:
B类的id字段值 - 值:所有包含该
id的A对象组成的列表 - 注意:
A类包含其他需要保留的字段,因此不能将结果改为Map<Integer, List<B>>。
示例
输入
[classBList=[B{id:1, name:"Hello"}, B{id:2, name:"Hi"}], classBList=[B{id:3, name:"No"}, B{id:3, name:"Go"}], classBList=[B{id:1, name:"Yes"}]]
输出
{Key=1, Value=[ A{classBList=[B{id:1, name:"Hello"}, B{id:1, name:"Yes"}]} ] {Key=2, Value=[ A{classBList=[B{id:2, name:"Hi"}]} ] {Key=3, Value=[ A{classBList=[B{id:3, name:"No"}, B{id:3, name:"Go"}]} ]
错误尝试代码
Map<Integer, List<A>> heyThere = classAListInput.stream() .collect(Collectors.toMap( A::getClass, element -> element.getClassBList().stream() .map(B::getId) .collect(Collectors.toList()) ));
代码问题分析
- 键类型错误:使用
A::getClass作为键生成器,实际是把A的Class对象作为键,完全不符合用B.id作为键的需求。 - 值类型不匹配:value生成器返回的是
List<Integer>(B的id列表),但目标Map的value类型是List<A>,导致编译错误。 - 未处理多id映射:一个
A对象可能包含多个不同id的B,原代码无法将同一个A分配到多个对应的id分组中。
正确实现代码
import java.util.AbstractMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; // 转换逻辑 Map<Integer, List<A>> result = classAListInput.stream() // 将每个A根据其包含的B的id,拆分为多个(id, A)键值对 .flatMap(a -> a.getClassBList().stream() .map(B::getId) .distinct() // 去重同一A内的重复id,避免A被重复加入同一分组 .map(id -> new AbstractMap.SimpleEntry<>(id, a)) ) // 按id分组,收集对应的A对象列表 .collect(Collectors.groupingBy( Map.Entry::getKey, Collectors.mapping(Map.Entry::getValue, Collectors.toList()) ));
代码逻辑说明
- 扁平化处理:通过
flatMap将每个A对象展开为多个(id, A)键值对,确保每个A会被分配到其包含的所有B.id对应的分组中。 - 去重处理:使用
distinct()避免同一A对象因内部包含重复id的B而被多次添加到同一分组列表。 - 分组收集:通过
Collectors.groupingBy按id分组,将对应的A对象收集为列表,得到符合需求的Map结构。
内容的提问来源于stack exchange,提问作者pleasedontbemeantome
相关产品推荐
相关产品推荐

