合并两个Map并保留null值,如何避免空指针异常?
合并两个Map并保留null值的解决方案
问题分析
你的代码目前存在两个核心问题:
Collectors.toMap底层依赖Map.merge的特性:当合并函数返回null时,Map.merge会自动移除对应的键,导致像k3这种两个值都是null的条目无法保留在结果中。- 潜在的NPE风险:虽然当前逻辑先判断
v1 != null再调用toString(),但如果后续逻辑调整,容易出现空指针异常,需要更严谨的处理。
修改后的代码
推荐使用更直观的forEach方式合并,既避免Map.merge的限制,又能清晰实现你的合并规则:
private Map<String, Object> mergeMaps(Map<String, Object> map1, Map<String, Object> map2) { // 先复制map1的所有条目,保留原始的null值 Map<String, Object> result = new HashMap<>(map1); // 遍历map2的每个条目,按规则合并 map2.forEach((key, v2) -> { Object v1 = result.get(key); // 合并规则:若v1非空且toString后不为空字符串,则保留v1;否则使用v2(包括v2为null的情况) if (!(v1 != null && StringUtils.isNotEmpty(v1.toString()))) { result.put(key, v2); } }); return result; }
代码说明
- 先复制
map1的所有内容,确保map1中的null值被保留。 - 遍历
map2时,对每个键执行合并逻辑:- 如果
v1符合保留条件(非空且转换为字符串后非空),则不修改结果。 - 否则(包括
v1为null、v1是空字符串等情况),用map2的值覆盖,即使v2是null也会保留。
- 如果
测试结果
运行你的测试代码,会得到期望的输出:
{k1=1, k2=2, k3=null}
补充说明
如果坚持使用Stream方式,需要注意Collectors.toMap结合Map.merge会自动移除null值的特性,这种方式无法保留k3这类双null的条目,因此不推荐使用。
内容的提问来源于stack exchange,提问作者Bourg
相关产品推荐
相关产品推荐

