map.put() 返回被替换的旧值,键存在时覆盖并返回旧值,不存在时返回 null;可据此区分新增与更新操作,避免额外 get() 调用,提升性能。

Java 中 Map.put(K key, V value) 方法在键已存在时会用新值覆盖旧值,并返回被替换的旧值;如果键不存在,则返回 null。这个返回值不是“操作是否成功”的标志,而是实际的旧值,正确利用它能避免额外的 get() 调用,提升性能和代码清晰度。
利用返回值判断是否为新增键
当需要区分“插入新键”和“更新已有键”两种逻辑时,可直接检查 put() 的返回值是否为 null(注意:前提是 map 中不存 null 值):
- 若返回
null,说明该键此前不存在,本次是首次插入 - 若返回非
null对象,说明发生了覆盖,原值已被替换
例如统计单词首次出现位置:
Mapfor (int i = 0; i if (firstSeen.put(words[i], i) == null) {
// 返回 null → 首次插入,可做初始化处理
System.out.println("首次见到 " + words[i] + " 在位置 " + i);
}
}
安全获取并处理被覆盖的旧值
有时需对旧值执行清理、日志或校验。直接使用返回值比先 get() 再 put() 更高效且线程安全(单次调用,无竞态):
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 避免两次哈希查找,减少开销
- 防止并发场景下两次调用之间值被其他线程修改
- 尤其适合缓存淘汰、资源释放等场景
例如缓存中替换对象前关闭其资源:
Resource old = cache.put(key, newResource);if (old != null) {
old.close(); // 安全释放旧资源
}
注意 null 值带来的歧义
如果 map 允许存储 null 值(如 HashMap),则 put() 返回 null 并不能确定是“键不存在”还是“键存在但值为 null”:
- 此时应改用
containsKey()配合get()判断,或使用compute()等更明确的方法 -
ConcurrentHashMap的put()同样返回旧值,但不支持null值,可规避该问题
替代方案:computeIfAbsent / computeIfPresent
对于更复杂的逻辑(如仅在键不存在时计算值,或仅在存在时更新),推荐使用 Java 8+ 的函数式方法,语义更清晰且线程安全:
-
computeIfAbsent(key, mappingFunction):键不存在才计算并放入 -
computeIfPresent(key, remappingFunction):键存在才对旧值做变换 - 它们内部也利用了类似
put()的原子性,但封装了条件逻辑
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










