compute
和computeIfAbsent
都是Map
接口中的默认方法,用于在映射中进行键值对的计算和更新。它们的主要区别在于它们的行为和使用场景。
compute
方法
定义:
V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction);
-
参数:
key
: 要计算其值的键。remappingFunction
: 用于计算新值的函数。它接受两个参数:键和当前值(如果键不存在,则当前值为null
),并返回一个新值。
-
行为:
- 如果键存在,
remappingFunction
会应用于当前键和值,并返回一个新的值。 - 如果键不存在,
remappingFunction
会应用于键和null
,并返回一个新的值。 - 如果
remappingFunction
返回null
,则从映射中删除该键。
- 如果键存在,
示例
import java.util.HashMap;
import java.util.Map;public class ComputeExample {public static void main(String[] args) {Map<String, Integer> map = new HashMap<>();map.put("a", 1);map.put("b", 2);// 使用 compute 更新已存在的值map.compute("a", (k, v) -> v == null ? 42 : v + 1);// 使用 compute 添加新值map.compute("c", (k, v) -> v == null ? 42 : v + 1);System.out.println(map); // 输出: {a=2, b=2, c=42}}
}
computeIfAbsent
方法
定义:
V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction);
-
参数:
key
: 要计算其值的键。mappingFunction
: 用于计算新值的函数。它接受一个参数:键,并返回一个新值。
-
行为:
- 如果键不存在,则
mappingFunction
会被调用来计算一个值,并将这个值与键关联。 - 如果键已经存在,则不会调用
mappingFunction
,直接返回当前值。
- 如果键不存在,则
示例
import java.util.HashMap;
import java.util.Map;public class ComputeIfAbsentExample {public static void main(String[] args) {Map<String, Integer> map = new HashMap<>();map.put("a", 1);map.put("b", 2);// 使用 computeIfAbsent 添加新值map.computeIfAbsent("c", k -> 42);// 使用 computeIfAbsent 不会更新已存在的值map.computeIfAbsent("a", k -> 42);System.out.println(map); // 输出: {a=1, b=2, c=42}}
}
区别总结
-
compute
:- 适用于需要根据键和值计算新值的情况。
- 即使键不存在,也会调用计算函数。
- 可以用于更新和删除键值对。
-
computeIfAbsent
:- 适用于仅在键不存在时计算新值的情况。
- 如果键已经存在,不会调用计算函数。
- 只能用于添加新键值对,不会更新已存在的键值对。
用法对比
import java.util.HashMap;
import java.util.Map;public class ComputeVsComputeIfAbsent {public static void main(String[] args) {Map<String, Integer> map = new HashMap<>();map.put("a", 1);map.put("b", 2);// 使用 compute 更新已存在的值map.compute("a", (k, v) -> v == null ? 42 : v + 1);// 使用 computeIfAbsent 添加新值map.computeIfAbsent("c", k -> 42);System.out.println(map); // 输出: {a=2, b=2, c=42}// 使用 computeIfAbsent 不会更新已存在的值map.computeIfAbsent("a", k -> 42);System.out.println(map); // 输出: {a=2, b=2, c=42}// 使用 compute 更新已存在的值map.compute("a", (k, v) -> v == null ? 42 : v + 1);System.out.println(map); // 输出: {a=3, b=2, c=42}}
}
通过这些示例,可以清楚地看到compute
和computeIfAbsent
的不同用法和行为。