putIfAbsent是HashMap的原子性方法,键不存在时插入并返回null,存在时返回旧值;适用于值已知场景,但需注意null值歧义,高开销构造推荐用computeIfAbsent。

putIfAbsent 是 HashMap 提供的原子性方法,能直接在插入前检查键是否已存在,避免手动先 containsKey 再 put 的冗余判断,既简洁又线程安全(对单个操作而言)。
核心作用:只在键不存在时才插入
该方法签名是:V putIfAbsent(K key, V value)。它会返回当前键关联的值:如果键原本就存在,返回已有值,不覆盖;如果键不存在,则插入新值并返回 null(注意:value 本身为 null 时也返回 null,需结合场景判断)。
常见误用是把它当“判断是否存在”用——其实它的主要价值在于“尝试插入 + 获取结果”,而非单纯做 if 判断。
替代 if-containsKey-put 的典型写法
传统写法需要两步,且非原子:
立即学习“Java免费学习笔记(深入)”;
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
if (!map.containsKey(key)) {
map.put(key, value);
}
用 putIfAbsent 一行搞定:
map.putIfAbsent(key, value);
更进一步,若需根据插入结果做不同处理(比如初始化对象),可利用其返回值:
- 返回
null→ 表示本次成功插入(键原不存在) - 返回非
null→ 表示键已存在,返回的是旧值
注意 null 值带来的歧义
由于 HashMap 允许 value 为 null,所以 putIfAbsent(key, null) 总是返回 null,无法区分“插入成功”还是“键已存在且值为 null”。因此:
- 尽量避免将
null作为有效业务值存入 map - 若必须支持 null value,建议改用
computeIfAbsent或显式判断get(key) == null && !containsKey(key)
与 computeIfAbsent 的区别
putIfAbsent 直接传入 value,适合值已知、开销小的场景;而 computeIfAbsent 接收一个 Function,仅在键缺失时才执行计算,适合值构造代价高或依赖上下文的情况:
// 值已知,用 putIfAbsent
map.putIfAbsent("user:1001", new User("Alice"));
// 值需查库或创建,用 computeIfAbsent 更高效
map.computeIfAbsent("user:1001", id -> loadUserFromDB(id));

















