如何合并两个HashMap并将值封装为指定类的对象?
如何合并两个HashMap并将值封装为指定类的对象?
嗨,我来帮你搞定这个问题!你想要把两个键完全相同的Double类型Map,合并成一个键对应Values对象的Map,同时把Double转成BigDecimal对吧?其实用Java Stream就能轻松实现,我给你一步步讲清楚:
首先,先给你的Values类加个构造方法吧,这样创建对象会方便很多(当然getter/setter和toString如果需要也加上):
public class Values { private BigDecimal a; private BigDecimal b; // 新增构造方法,直接初始化两个字段 public Values(BigDecimal a, BigDecimal b) { this.a = a; this.b = b; } // 可选:重写toString方便查看结果 @Override public String toString() { return "Values{a=" + a + ", b=" + b + "}"; } // 按需添加getter/setter public BigDecimal getA() { return a; } public BigDecimal getB() { return b; } }
接下来就是核心的合并代码了,用Stream和Collectors就能搞定:
Map<String, Double> map1 = Map.of("A", 123.1, "B", 345.2, "C", 678.3); Map<String, Double> map2 = Map.of("A", 543.5, "B", 432.2, "C", 654.3); // 合并成目标Map<String, Values> Map<String, Values> map3 = map1.keySet().stream() .collect(Collectors.toMap( // 键保持原有的字符串键 key -> key, // 每个键对应生成Values对象,注意转BigDecimal的正确姿势 key -> new Values( BigDecimal.valueOf(map1.get(key)), BigDecimal.valueOf(map2.get(key)) ) )); // 测试输出结果 map3.forEach((k, v) -> System.out.println(k + " -> " + v));
几个关键细节要注意:
- BigDecimal的转换方式:一定要用
BigDecimal.valueOf(double),而不是直接new BigDecimal(double)!因为浮点数本身有精度隐患,直接用double构造BigDecimal会出现类似0.1变成0.10000000000000000555...的问题,valueOf方法会帮我们避免这个坑。 - 关于“不用显式创建第三个Map”:其实合并后的结果肯定需要一个容器存储,但如果你是指不用手动
new HashMap(),那上面的代码已经做到了——Collectors.toMap会自动帮我们创建默认的HashMap实现。甚至你可以直接把合并后的结果拿去用,不用赋值给变量,比如直接遍历:// 直接使用合并结果,不赋值给map3变量 map1.keySet().stream() .collect(Collectors.toMap( key -> key, key -> new Values( BigDecimal.valueOf(map1.get(key)), BigDecimal.valueOf(map2.get(key)) ) )) .forEach((k, v) -> System.out.println(k + " -> " + v));
额外补充:处理键不完全一致的情况
如果以后你的两个Map可能出现键不匹配的情况(比如某个键只在其中一个Map里),可以用Stream.concat合并两个Map的键并去重,再用getOrDefault避免空指针:
Map<String, Values> map3 = Stream.concat(map1.keySet().stream(), map2.keySet().stream()) .distinct() .collect(Collectors.toMap( key -> key, key -> new Values( BigDecimal.valueOf(map1.getOrDefault(key, 0.0)), BigDecimal.valueOf(map2.getOrDefault(key, 0.0)) ) ));
这里用0.0作为缺失键的默认值,你可以根据自己的需求改成其他值。
备注:内容来源于stack exchange,提问作者Alexander Konev
相关产品推荐
相关产品推荐

