computeIfPresent源码分析及案例

点赞在看,养成习惯。

点赞收藏,人生辉煌。

点击关注【微信搜索公众号:编程背锅侠】,防止迷路。

方法概述

如果指定键的值存在且非空,则尝试根据给定键及其当前映射值,计算新映射。

如果函数返回 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);
	}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/wildwolf_001/article/details/106907614