天天看点

map computeIfAbsent 的浅尝辄止

今天一不心,误用这个方法,一直认为computeIfAbsent的value再次调用时,value也会随之更新,但在做单元测试时发现这个值并不是那样的,使用这个方法,map中的value只会当key不存在时,创建key,并put进value,一旦key存在,调用这个方法,还是最近一次put进的value,并非是你想要更新的结果.索性写了一个测试,去验证了一下,代码如下

Map<String, String> map = new HashMap<>();
        String result = map.computeIfAbsent("test", k -> "testAbsent");
        System.out.println(result);
        result = map.computeIfAbsent("test", k -> "updateAbsent");
        System.out.println(result);

        System.out.println(map);
           

执行结果如下:

map computeIfAbsent 的浅尝辄止

验证了之前的想法后,要去看map的源码实现是怎么搞的了,

default V computeIfAbsent(K key,
            Function<? super K, ? extends V> mappingFunction) {
        Objects.requireNonNull(mappingFunction);
        V v;
        if ((v = get(key)) == null) {
            V newValue;
            if ((newValue = mappingFunction.apply(key)) != null) {
                put(key, newValue);
                return newValue;
            }
        }

        return v;
    }
           

从源码上看,只有当get key为空时,会把新值put到map并且返回,反之返回原来的值。

总结,put只是简单的添加,当map中存在对应Key的时候,put会覆盖掉原本的value值,并返回覆盖前的value,不存在时,返回null.而computeIfAbsent顾名思义,会检查map中是否存在Key值,如果存在会检查value值是否为空,如果为空就会将K值赋给value,否则返回get到的key值。