Java 8新特性(6) Map 新增方法

  1. forEach
  2. putIfAbsent
  3. computeIfPresent
  4. computeIfAbsent
  5. compute
  6. remove(Object key, Object value)
  7. getOrDefault
  8. replace
  9. replaceAll
  10. merge
  11. 参考

在 Java 8 中的 Map 接口增加了一些 default 方法,提升了对 key, value 操作的便利性。

Map<Integer, String> map = new HashMap<>();

for (int i = 0; i < 10; i++) {
    map.put(i, "val" + i);
}

forEach

遍历 Map 中的所有 Entry, 对 key, value 进行处理, 接收参数 (K, V) -> void

map.forEach((id, val) -> System.out.println(val));
// val0
// val1
// val2
// ...

putIfAbsent

如果 key 存在,则返回 value 值,否则相当于普通 put 操作

map.putIfAbsent(3, "123")  // val3,未更新
map.putIfAbsent(33, "val33")  // null,put

// 相当于
V v = map.get(key);
if (v == null)
    v = map.put(key, value);

return v;

computeIfPresent

  1. 如果指定的 key 存在,则根据旧的 key 和 value 计算新的值 newValue
    • 如果 newValue 不为 null,则设置 key 新的值为 newValue;
    • 如果 newValue 为 null,则删除该 key 的值;
  2. 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;
    }
}
// 如果 newValue 不为null,则设置 key 新的值为 newValue
map.computeIfPresent(3, (num, val) -> val + num);  // val33
map.get(3); // val33

// 如果 newValue 为 null,则删除该 key 的值
map.computeIfPresent(9, (num, val) -> null);  // null
map.containsKey(9);  // false

computeIfAbsent

如果指定的 key 不存在,则通过指定的 K -> V 计算出新的值设置为 key 的值,类似代码如下:

// 源码
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;
}
map.computeIfAbsent(23, num -> "val" + num);  // val23
map.containsKey(23);  // true

map.computeIfAbsent(3, num -> "bam");  // val33
map.get(3);  // val33

compute

  1. 则根据旧的 key 和 value 计算新的值 newValue
  2. 如果 newValue 不为 null,则 put(key, newValue); return newValue;
  3. 如果 newValue 为 null
    • 如果 key 存在,或 oldValue 为 null,则删除该 key,return null;
    • 如果 key 不存在,则 return null
// 源码
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;
    }
}
map.compute(3, (num, val) -> val + num);  // val333
map.get(3);  // val333

map.compute(8, (num, val) -> null);  // null
map.containsKey(8);  // false

map.compute(19, (num, val) -> val + num);  // null19
map.containsKey(19);  // true

remove(Object key, Object value)

接收 2 个参数,key 和 value,如果 key 关联的 value 值与指定的 value 值相等(equals),则删除这个元素

map.remove(3, "val3");  // false
map.get(3);  // val33

map.remove(3, "val33");  // true
map.get(3);  // null

getOrDefault

如果指定的 key 存在,则返回该 key 对应的 value,如果不存在,则返回指定的值。

map.getOrDefault(42, "not found");  // not found

replace

replace(K key, V oldValue, V newValue):如果 key 关联的值与指定的 oldValue 的值相等,则替换成新的 newValue,返回 boolean。

replace(K key, V value):如果 map 中存在 key,则替换成 value 值,返回原 value 值,否则返回 null。

map.replace(2, "val2", "val22");  // true
map.get(2);  // val22
map.replace(2, "val2");  // val22,返回原 value 值
map.get(2);  // val2

replaceAll

替换 Map 中所有 Entry 的 value 值,这个值由旧的 key 和 value 计算得出,接收参数 (K, V) -> V

System.out.println(map);  // {0=val0, 1=val1, 33=val33, 2=val2, ...
map.replaceAll((key, value) -> (key + 1) + value);
System.out.println(map);  // {0=1val0, 1=2val1, 33=34val33, 2=3val2, ...

merge

  1. oldValue = get(key);
    • 指定的 key 不存在,则 newValue 为指定的 value 值
    • 指定的 key 存在,则根据 key 的旧的值 oldvalue 和 value 计算出新的值 newValue
  2. 判断 newValue
    • newValue 为 null,则 remove(key);
    • newValue 不为 null,put(key, newValue);
  3. return newValue;
// 源码
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;
}
map.merge(9, "val9", (value, newValue) -> value.concat(newValue));  // val9
map.get(9);  // val9

map.merge(9, "concat", (value, newValue) -> value.concat(newValue));  // val9concat
map.get(9);  // val9concat

参考

https://wizardforcel.gitbooks.io/modern-java/content/ch1.html


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 bin07280@qq.com

文章标题:Java 8新特性(6) Map 新增方法

文章字数:981

本文作者:Bin

发布时间:2019-03-13, 21:16:22

最后更新:2019-08-06, 00:07:35

原始链接:http://coolview.github.io/2019/03/13/Java8/Java%208%E6%96%B0%E7%89%B9%E6%80%A7(6)%20Map%20%E6%96%B0%E5%A2%9E%E6%96%B9%E6%B3%95/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录