computeIfPresent是Map中严格限定“键存在且值非null时才执行更新”的原子方法,由ConcurrentHashMap等实现保障线程安全,返回null则删除键,适用于计数器累加、状态流转等条件更新场景。

computeIfPresent 是 Map 接口提供的一个原子方法,只在键存在且对应值非 null 时才执行计算,并用结果替换原值。它不是“先 get 再 put”的简单组合,而是由具体实现(如 ConcurrentHashMap)保障线程安全的单次操作。
触发条件:键必须存在且当前值不能为 null
该方法不会处理键不存在的情况(此时应使用 computeIfAbsent),也不会对 value == null 的键做任何操作——即使键存在,只要其映射值为 null,就跳过计算逻辑。
- ConcurrentHashMap 中,这个判断和更新是在同一把锁(或 CAS 操作)下完成的,避免竞态
- HashMap 虽也支持该方法,但不保证线程安全;多线程环境下必须配合外部同步
- 注意:null 值本身是合法的 map value,但 computeIfPresent 明确将其视为“不满足执行条件”
参数含义:key + BiFunction<K,V,V>
第二个参数是一个接受 key 和当前 value 的函数,返回新 value。返回 null 表示删除该键值对(等价于 remove(key))。
- 函数内可安全访问 key 和旧值,无需额外校验
- 若函数抛出异常,整个操作失败,map 状态不变
- 返回 null 会移除键,不是保留原值;想保留原值需显式返回旧值
典型使用场景:计数器累加、状态流转、条件更新
适合需要“读-改-写”但又不想引入显式同步或额外判断的场景。
立即学习“Java免费学习笔记(深入)”;
- 比如统计单词出现次数:
map.computeIfPresent("word", (k, v) -> v + 1) - 订单状态变更:仅当当前状态为 "PENDING" 才允许设为 "CONFIRMED"
- 缓存刷新:仅当缓存项存在且未过期时,用新数据更新其时间戳
与 compute、merge 的关键区别
computeIfPresent 是三者中约束最强、行为最明确的一个:
- compute:无论键是否存在、值是否为 null,都会调用函数;函数返回 null 则删除键
- merge:键不存在时用默认值,存在时用函数合并新旧值;语义更偏向“合并”而非“条件更新”
- computeIfPresent:严格限定于“有值才更新”,语义清晰,不易误用


















