在日常使用 Map
的时候,我们经常会遇到这样的需求:
- 如果 key 存在就更新它;
- 如果满足某个条件就删除它;
- 如果不存在就插入新值。
那么问题来了:Map.compute
方法能不能用来删除元素?
compute 方法的语义
Map.compute(key, remappingFunction)
的定义是这样的:
- 获取 key 对应的旧值(可能为
null
); - 将
key
和旧值传给remappingFunction
; - 如果返回值 非 null,则作为新值放入
Map
; - 如果返回值 null,则表示移除该 key 对应的映射(如果存在)。
换句话说:
👉 返回 null 就是删除,返回非 null 就是更新或插入。
示例代码
Map<String, Integer> map = new HashMap<>(); map.put("a", 1); // 使用 compute 删除 key "a" map.compute("a", (k, v) -> null); System.out.println(map.containsKey("a")); // false
输出结果为 false
,说明元素已经被删除。
注意事项
- 原子性
- 在
ConcurrentHashMap
中,compute
同样具备原子语义,可以安全地在并发场景下使用。
- 在
- key 不存在的情况
- 如果 key 不存在,
compute
的 remappingFunction 收到的旧值为null
。 - 如果此时返回
null
,不会有任何变化。
- 如果 key 不存在,
- 适用场景
- 当你想要根据旧值来决定“更新还是删除”时,
compute
非常合适。
- 当你想要根据旧值来决定“更新还是删除”时,
和其他方法的对比
computeIfPresent(key, remappingFunction)
- 只在 key 存在时才调用函数。
- 返回 null 也会删除元素。
computeIfAbsent(key, mappingFunction)
- 只在 key 不存在时才调用函数。
- 返回 null 时不会插入新值。
因此,如果你需要统一处理“更新或删除”的逻辑,compute
是最通用的方法。
总结
Map.compute
不仅能更新和插入元素,还能通过返回 null
来 删除元素。
它是 Map
接口在 Java 8 引入的增强方法之一,为我们简化了“查找 → 判断 → 更新/删除”的繁琐流程。
在实际开发中,合理使用 compute
、computeIfPresent
和 computeIfAbsent
,可以让你的代码更简洁、更具表达力。