在 jdk 8 中,`hashmap` 的 `compute` 系列方法(包括 `compute`、`computeifabsent`、`computeifpresent`)用于原子性地计算或更新键值对的值。这些方法的核心优势在于:如果计算结果为 `null`,则自动移除该键;同时它们接受一个 `bifunction` 作为参数,能够安全地基于旧值计算新值,避免了并发修改异常和重复查找的性能损耗。

computeIfAbsent 在键不存在时如何工作
computeIfAbsent 仅在指定键尚未映射到值(或映射为 null)时执行计算函数。它接收两个参数:目标键和一个 Function super K, ? extends V> 函数。只有当键缺失时,才会调用该函数生成新值并放入 Map;若键已存在,则直接返回现有值且不触发函数调用。这非常适合懒加载场景,例如缓存初始化。

import java.util.HashMap;
import java.util.Map;
public class ComputeDemo {
public static void main(String[] args) {
Map<string string> map = new HashMap();
// 键 "key1" 不存在,触发计算
String val1 = map.computeIfAbsent("key1", k -> "Value for " + k);
System.out.println("val1: " + val1); // 输出: Value for key1
// 键 "key1" 已存在,不触发计算
String val2 = map.computeIfAbsent("key1", k -> "New Value");
System.out.println("val2: " + val2); // 输出: Value for key1
}
}</string>
computeIfPresent 在键存在时如何工作
computeIfPresent 仅在指定键当前映射到一个非 null 的值时才执行计算函数。它接收目标键和一个 BiFunction super K, ? super V, ? extends V> 函数。该函数接收键和当前值作为参数,返回新值。如果计算结果返回 null,则该键-值映射会被从 Map 中移除。这在需要根据旧值动态调整或删除条目时非常有用。

import java.util.HashMap;
import java.util.Map;
public class ComputeDemo {
public static void main(String[] args) {
Map<string integer> map = new HashMap();
map.put("count", 5);
// 键 "count" 存在,值为 5,触发计算
// 新值 = 旧值 * 2
Integer newVal = map.computeIfPresent("count", (k, v) -> v * 2);
System.out.println("newVal: " + newVal); // 输出: 10
System.out.println("map: " + map); // 输出: {count=10}
// 模拟移除操作
map.computeIfPresent("count", (k, v) -> null);
System.out.println("map after remove: " + map); // 输出: {}
}
}</string>
使用 compute 无条件更新或移除键值对
compute 方法总是执行计算函数,无论键是否存在。它接收目标键和一个 BiFunction super K, ? super V, ? extends V> 函数。该函数接收键和当前值(如果键不存在,则当前值为 null)。根据函数的返回值:
1. 如果返回值非 null,则更新或插入该键值对。
2. 如果返回值是 null,则从 Map 中移除该键(如果存在)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











