点赞在看,养成习惯。
点赞收藏,人生辉煌。
点击关注【微信搜索公众号:编程背锅侠】,防止迷路。
方法概述
如果指定键的值存在且非空,则尝试根据给定键及其当前映射值,计算新映射。
如果函数返回 null,则将删除该映射。如果函数本身引发(未经检查的)异常,则该异常将被重新抛出,并且当前映射保持不变。
请求参数
- key 指定的值将与之相关联。
- mappingFunction 计算数值的函数。
返回值
与指定键关联的新值;如果没有,则返回null。
异常情况
- 如果指定的键为空,而这个映射不支持空键,或者映射函数为空,则抛出NullPointerException。
- 如果该集合不支持put操作,则出现UnsupportedOperationException异常。
- 如果指定的键或值的类阻止它被存储在这个映射中,则ClassCastException异常。
源码分析
default V computeIfPresent(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
// 这个计算数值的函数为空,则抛出空指针异常
Objects.requireNonNull(remappingFunction);
V oldValue;
// 根据指定的key获取值,赋值给oldValue
if ((oldValue = get(key)) != null) {
// 旧的值存在,使用计算函数使用指定的key和旧值计算出新值
V newValue = remappingFunction.apply(key, oldValue);
// 判断新值是否为空
if (newValue != null) {
// 新值不为空,将新值添加到ma p集合中
put(key, newValue);
// 返回新值
return newValue;
} else {
// 新值为空,删除这个指定的key
remove(key);
// 返回null
return null;
}
} else {
// 根据指定的key拿不到旧的值,直接返回null
return null;
}
}
总结
- 给定的key在集合中无法获取到旧的val,或者获取到的旧的val为null,直接返回null。
- 根据我们自定义的计算函数和给定的key以及通过给定key获取到的旧的val,计算出一个新的val。
- 如果新的val不为null,将key和新的val添加到集合。否则新的val为null,删除这个key并且,直接返回null.
包含指定key的测试案例
@Test
public void test_computeIfPresent(){
Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
Set<String> s = new HashSet<>();
String canonicalName = "m";
s.add("mm");
dependentBeanMap.put(canonicalName, s);
// 判断这个key对应的val是否存在,存在就根据我们定义的计算函数给这个key计算一个新的val,这个返回值就是经过计算函数以后的新的val
Set<String> dependentBeans =
dependentBeanMap.computeIfPresent(canonicalName, (k, v) -> {
v.add("hahh");
return v;
});
// 获取这个元素对应的val值,并遍历, 这时候会打印出这个key对应的val的set集合中有两个值
dependentBeanMap.get(canonicalName).forEach(System.out::println);
System.out.println();
// set集合返回值的遍历,返回值其实就是key对应的val的值
assert dependentBeans != null;
dependentBeans.forEach(System.out::println);
}
不包含指定key的测试案例
/**
* map集合中包含这个key
*/
@Test
public void test_computeIfPresent_contains_no(){
Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
String canonicalName = "m";
// 判断这个key对应的val是否存在,存在就根据我们定义的计算函数给这个key计算一个新的val
Set<String> dependentBeans =
dependentBeanMap.computeIfPresent(canonicalName, (k, v) -> {
v.add("hahh");
return v;
});
// 判断这个集合中是否包含这个key
System.out.println(dependentBeanMap.containsKey(canonicalName));// false
// 执行这一行的时候会报错NullPointerException异常
Set<String> strings = dependentBeanMap.get(canonicalName);
assert strings != null;
strings.forEach(System.out::println);
}