java合并map的核心是明确冲突处理逻辑:putall()简单覆盖,merge()支持自定义合并(如累加),stream.collect()生成新map并灵活指定冲突策略,computexxx适用于老版本或细粒度控制。

HashMap 合并两个 Map 的核心在于:明确你想要的冲突处理逻辑——是简单覆盖、保留旧值、累加数值,还是自定义规则。Java 提供了多种方式,各有适用场景,选错容易导致数据丢失或逻辑错误。
用 putAll() 快速覆盖合并
适合无重复 key 或明确接受后写入值覆盖前值的场景。它不判断、不计算,直接把第二个 Map 的所有条目逐个 put 进目标 Map。
- 操作简单,性能好,但完全不处理“相同 key 值怎么融合”的问题
- 如果 map1 有
{"A": 1},map2 有{"A": 100},合并后A的值就是100,原值被丢弃 - 推荐用于配置加载、兜底值注入、批量导入且已确认 key 不重叠的情况
用 merge() 实现带逻辑的合并
这是 Java 8+ 推荐的主流方式,尤其适合需要对重复 key 的 value 做运算(如求和、取大、拼接)的场景。它原子性地判断键是否存在,并执行你指定的合并函数。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 语法:
targetMap.merge(key, value, (oldVal, newVal) -> yourLogic) - 例如数值累加:
mergedMap.merge(key, val, Integer::sum) - 保留旧值:
(oldVal, newVal) -> oldVal;保留新值:(oldVal, newVal) -> newVal - 注意:不是所有 Map 实现都支持 merge(),HashMap、ConcurrentHashMap、TreeMap 支持;ImmutableMap 等不可变实现会抛异常
用 Stream.concat() 构建新 Map
适合函数式风格编码,或需合并多个 Map、同时去重/转换/过滤的场景。它不修改原 Map,而是生成一个全新 Map。
- 示例:
Stream.concat(map1.entrySet().stream(), map2.entrySet().stream())<br>.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2) -> v2))
- 第三个参数是冲突解决器,
(v1, v2) -> v2表示用 map2 的值覆盖 - 优势是链式清晰、可扩展性强;劣势是创建中间 Stream 和对象,内存开销略高
手动遍历 + computeXXX 组合(兼容老版本或特殊需求)
当项目受限于 Java 7 或使用了不支持 merge() 的第三方 Map 类型时,可用 computeIfAbsent() 和 computeIfPresent() 手动控制逻辑。
- 例如累加:
mergedMap.compute(key, (k, v) -> v == null ? value : v + value) - 比裸写 for + if/else 更简洁安全,也比 putAll + 二次遍历更高效
- 适用于需要细粒度控制、或在并发环境下配合锁做复合操作的场景










