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);
	}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞流2023

小主,破费了,回头请你喝咖啡!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值