Java中如何将自定义对象List转换为Map of Map嵌套结构
实现步骤与完整代码
首先需要给原MyObject类补充对应字段的getter方法(Java Stream方法引用依赖getter访问字段),补全后的类定义如下:
class MyObject{ String division; String subDivision; Integer size; public MyObject(String division, String subDivision, Integer size) { this.division = division; this.subDivision = subDivision; this.size = size; } // 补充getter方法 public String getDivision() { return division; } public String getSubDivision() { return subDivision; } public Integer getSize() { return size; } }
最简洁的流式转换写法用Collectors.groupingBy嵌套Collectors.toMap实现,补全后的转换代码如下:
List<MyObject> list = Arrays.asList(new MyObject("A", "AA", 4), new MyObject("A", "AB", 2), new MyObject("A", "AC", 3), new MyObject("B", "BA", 11), new MyObject("B", "BB", 7), new MyObject("C", "CA", 8)); Map<String, Map<String,Integer>> map = list.stream().collect( // 外层Map按division分组 Collectors.groupingBy( MyObject::getDivision, // 分组后的元素转为内层Map,key为subDivision,value为size Collectors.toMap(MyObject::getSubDivision, MyObject::getSize) ) );
特殊场景处理
如果业务中存在同一个division下重复subDivision的场景,内层toMap会抛出键冲突异常,可以添加第三个参数指定冲突处理策略,示例如下:
// 冲突时保留新的size值 Collectors.toMap(MyObject::getSubDivision, MyObject::getSize, (oldSize, newSize) -> newSize) // 冲突时对size求和 Collectors.toMap(MyObject::getSubDivision, MyObject::getSize, Integer::sum)
沿用原代码toMap开头的写法
如果你需要保留原代码中Collectors.toMap开头的写法,可以参考如下实现:
Map<String, Map<String,Integer>> map = list.stream().collect(Collectors.toMap( MyObject::getDivision, // 单个元素生成内层Map obj -> { Map<String, Integer> inner = new HashMap<>(); inner.put(obj.getSubDivision(), obj.getSize()); return inner; }, // 同一个division的多个内层Map合并 (existInner, newInner) -> { existInner.putAll(newInner); return existInner; } ));
内容的提问来源于stack exchange,提问作者gstackoverflow
相关产品推荐
相关产品推荐

