最常用且推荐的方式是使用 putAll() 方法,它将源 Map 键值对复制到目标 Map 并覆盖重复键的值;也可新建 Map 复制后合并以避免修改原对象;Java 8+ 还支持 Stream + Collectors 自定义冲突策略。

Java 中批量合并两个 HashMap,最常用且推荐的方式是使用 putAll() 方法。它会将源 Map 中的所有键值对复制到目标 Map 中,如果键已存在,则新值会覆盖旧值(即“后写入优先”)。
用 putAll() 合并(最简单直接)
这是标准、高效、线程不安全但日常开发中最常用的方案:
- 调用方 Map(目标)执行
putAll(另一个Map) - 原 Map 不受影响;目标 Map 被修改(注意是“就地合并”)
- 若 key 冲突,后加入的值会覆盖原有值
Map<String, Integer> map1 = new HashMap<>() {
put("a", 1);
put("b", 2);
};
Map<String, Integer> map2 = new HashMap<>() {
put("b", 3); // 与 map1 冲突
put("c", 4);
};
map1.putAll(map2); // 合并后:{"a":1, "b":3, "c":4}
创建新 Map 合并(不修改原对象)
如果不想改变原始两个 Map,可以新建一个 Map 并分别 putAll:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 先复制第一个 Map(如用构造函数
new HashMap(map1)) - 再对副本调用
putAll(map2) - 返回这个新 Map,完全无副作用
Map<String, Integer> merged = new HashMap<>(map1); merged.putAll(map2); // map1 和 map2 均未被修改
用 Stream + Collectors 合并(支持自定义冲突策略)
Java 8+ 可用 Stream 流式合并,适合需要精细控制重复 key 处理逻辑的场景(比如取较大值、求和、拼接等):
立即学习“Java免费学习笔记(深入)”;
- 把两个 Map 的 entrySet 合并成一个流
- 用
Collectors.toMap()收集,第三个参数指定冲突时的合并函数 - 注意:key 冲突时必须显式处理,否则抛
IllegalStateException
Map<String, Integer> merged = Stream.concat(map1.entrySet().stream(), map2.entrySet().stream())
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(v1, v2) -> v1 + v2 // 冲突时相加,也可写 Math.max(v1,v2) 等
));
注意点和常见误区
合并过程看似简单,但几个细节容易出错:
-
空值检查:传入 null Map 会触发
NullPointerException,建议提前判空 -
线程安全:HashMap 本身非线程安全,多线程并发合并需额外同步或改用
ConcurrentHashMap - key 类型一致性:确保两个 Map 的 key 类型兼容(如都是 String),否则运行时可能因 equals/hashCode 行为异常导致合并失败
- value 为 null:HashMap 允许 value 为 null,但某些工具类或框架对 null value 敏感,合并后需留意业务逻辑是否兼容

















