天天看點

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值。