JAVA Map类提供了compute方法,定义是: default V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)
用于计算指定key的值,如果Map中不存在指定的key,则计算时值为null, 并将计算的结果作为key的值,但需要注意3点:
-
如果remappingFunction函数的结果是null, 如果Map存在此key且值不为null,则删除此key, 否则不做改变
-
如果remappingFunction函数抛出了异常,则compute把异常抛出,Map不做改变
-
默认实现不保证同步或该方法的原子性。任何实现提供原子性保证必须重写这个方法并记录它并发性能,如ConcurrentMap类的实现
compute方法接受两个参数
-
key:关联value的key
-
remappingFunction: 函数计算值
Returns:返回更新后的该key映射的value值,若key没有映射的value值,则返回null
1. 源码实现:
default V compute(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
V oldValue = get(key);
V newValue = remappingFunction.apply(key, oldValue);
if (newValue == null) {
// delete mapping
if (oldValue != null || containsKey(key)) {
// something to remove
remove(key);
return null;
} else {
// nothing to do. Leave things as they were.
return null;
}
} else {
// add or replace old mapping
put(key, newValue);
return newValue;
}
}
2. 相似的方法
分别是指定的key存在和不存在情况时,使用remappingFunction计算新值,如果新值不为null,则将key的值设置为新值
default V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)
default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
3. 示例代码段
#创建或追加内容到指定的key, 作用类似于 map.merge(key, msg, String::concat)
map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg))}
#创建或累加计算指定key的次数
map.compute(type, (k, v) -> v == null ? 1 : v + 1);