# Java8给Map新增了几个default方法

default修复符也是Java8新增的,用于为接口配置非接口方法,提供默认实现。 Map中的几个default方法,有部分是之前就有的抽象方法,也有部分是Java8新增的,以下我们一起来了解新增的这些默认实现。

# compute

此方法本意是"计算",是指针对指定key写入一段计算逻辑的函数remappingFunction,其函数核心逻辑是为其key创建或计算出一个新的value

源码如下:

default V compute(K key,
        BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
    Objects.requireNonNull(remappingFunction);
    V oldValue = get(key);
    V newValue = remappingFunction.apply(key, oldValue);
    if (newValue == null) {
        // delete mapping
        if (oldValue != null || containsKey(key)) {
            // something to remove
            remove(key);
            return null;
        } else {
            // nothing to do. Leave things as they were.
            return null;
        }
    } else {
        // add or replace old mapping
        put(key, newValue);
        return newValue;
    }
}

# computeIfAbsent

方法表示:如果key的值不存在,则执行compute(计算),并将"计算函数"的返回值put进去,如果key的值存在,则直接返回其value。

源码如下:

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;
}
# 常用场景

用于设置默认值

# computeIfPresent

方法表示:如果key的值存在则进行计算,并将"计算函数"的返回值替换原值;如果key的值不存在,则直接返回null。

源码如下:

default V computeIfPresent(K key,
        BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
    Objects.requireNonNull(remappingFunction);
    V oldValue;
    if ((oldValue = get(key)) != null) {
        V newValue = remappingFunction.apply(key, oldValue);
        if (newValue != null) {
            put(key, newValue);
            return newValue;
        } else {
            remove(key);
            return null;
        }
    } else {
        return null;
    }
}
# 常用场景

# getOrDefault

根据下面源码即可知:如果key存在,则返回其对用的value;如果key不存在,则返回默认值(另一个入参)。

源码如下:

 default V getOrDefault(Object key, V defaultValue) {
     V v;
     return (((v = get(key)) != null) || containsKey(key))
         ? v
         : defaultValue;
 }

# merge

如果key的原值为null,则用新值(入参),如果key的原值不为null,则调用"函数逻辑"(入参)获取返回值。最终得到的值如果为null,则将key移除,如果不为null,则替换原有值。

源码如下:

default V merge(K key, V value,
        BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
    Objects.requireNonNull(remappingFunction);
    Objects.requireNonNull(value);
    V oldValue = get(key);
    V newValue = (oldValue == null) ? value :
               remappingFunction.apply(oldValue, value);
    if(newValue == null) {
        remove(key);
    } else {
        put(key, newValue);
    }
    return newValue;
}

# putIfAbsent

如果key的值为null(或者不存在),则put。

源码如下:

default V putIfAbsent(K key, V value) {
    V v = get(key);
    if (v == null) {
        v = put(key, value);
    }
    return v;
}

# remove

如果key的原值与value相等,则remove

源码如下:

default boolean remove(Object key, Object value) {
    Object curValue = get(key);
    if (!Objects.equals(curValue, value) ||
        (curValue == null && !containsKey(key))) {
        return false;
    }
    remove(key);
    return true;
}

# replace

功能显而易见。

源码如下:

default V replace(K key, V value) {
    V curValue;
    if (((curValue = get(key)) != null) || containsKey(key)) {
        curValue = put(key, value);
    }
    return curValue;
}
# 另一个replace:
default boolean replace(K key, V oldValue, V newValue) {
    Object curValue = get(key);
    if (!Objects.equals(curValue, oldValue) ||
        (curValue == null && !containsKey(key))) {
        return false;
    }
    put(key, newValue);
    return true;
}

# replaceAll

循环map,执行"入参函数"的逻辑并获取返回值,将返回值赋值给value。 其实就是循环执行你传入的函数逻辑,替换所有的原值。

源码如下:

default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
    Objects.requireNonNull(function);
    for (Map.Entry<K, V> entry : entrySet()) {
        K k;
        V v;
        try {
            k = entry.getKey();
            v = entry.getValue();
        } catch(IllegalStateException ise) {
            // this usually means the entry is no longer in the map.
            throw new ConcurrentModificationException(ise);
        }
        // ise thrown from function is not a cme.
        v = function.apply(k, v);
        try {
            entry.setValue(v);
        } catch(IllegalStateException ise) {
            // this usually means the entry is no longer in the map.
            throw new ConcurrentModificationException(ise);
        }
    }
}
修改于: 8/11/2022, 3:17:56 PM