putIfAbsent是HashMap的原子性方法,仅当键不存在时插入值,返回null表示插入成功、非null为原有值,value不可为null。

putIfAbsent 是 HashMap 提供的原子性方法,用于“仅当键不存在时才插入值”,能安全避免意外覆盖已有数据。
核心作用:有则不动,无则插入
它等价于下面的手动检查逻辑,但更简洁、线程安全(在单个 map 操作层面):
if (!map.containsKey(key)) {
map.put(key, value);
}
而 putIfAbsent(key, value) 一行就搞定,且底层由 JDK 保证该操作不可被其他线程打断(对同一个 map 实例而言)。
基本用法示例
常见于缓存初始化、默认值设置等场景:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 为某个用户 ID 设置首次登录时间(只设一次)
- 给配置项提供默认值(已有值不替换)
- 统计类场景中初始化计数器(如 map.putIfAbsent(id, 0))
代码示例:
Map<String, String> userProfiles = new HashMap<>();
userProfiles.putIfAbsent("u1001", "default-profile"); // 插入成功
userProfiles.putIfAbsent("u1001", "updated-profile"); // 不生效,值仍是"default-profile"
System.out.println(userProfiles.get("u1001")); // 输出:default-profile
返回值很重要:判断是否真的插入了
putIfAbsent 返回的是该 key 对应的当前值 —— 如果 key 原本就存在,返回旧值;如果插入成功,返回 null(注意:value 本身可以是 null,但 putIfAbsent 不允许 value 为 null)。
- 返回 null → 表示本次插入成功,之前没有这个 key
- 返回非 null → 表示 key 已存在,返回的是原有 value
所以你可以这样写来响应不同情况:
String oldValue = map.putIfAbsent("key", "new-value");
if (oldValue == null) {
System.out.println("新键,已插入");
} else {
System.out.println("键已存在,原值为:" + oldValue);
}
注意事项
- value 不能为 null,否则抛 NullPointerException
- 它只保证单次操作的原子性,不适用于复合逻辑(比如“先查再算再存”),此时需配合 computeIfAbsent 或显式同步
- 在多线程环境下,多个线程同时调用 putIfAbsent 同一个 key,最多只有一个成功插入,其余拿到的是已有值 —— 这正是你要的效果
不复杂但容易忽略细节。

















