8.6.1 Java 8为Map新增的方法

8.6.1 Java 8为Map新增的方法

Java 8除为Map增加了remove(Object key,Object value)默认方法之外,还增加了如下方法。

compute方法

方法 描述
default V compute(K key, BiFunction<? super K,​? super V,​? extends V> remappingFunction) Attempts to compute a mapping for the specified key and its current mapped value (or null if there is no current mapping).

该方法使用remappingFunction根据原key-value对计算一个新value

  • 只要新value不为null,就使用新value覆盖原 value;
  • 如果原value不为null,但新valuenull,则删除原key-value对;
  • 如果原value、新value同时为null,那么该方法不改变任何key-value对,直接返回null

computeIfAbsent方法

方法 描述
default V computeIfAbsent(K key, Function<? super K,​? extends V> mappingFunction) If the specified key is not already associated with a value (or is mapped to null), attempts to compute its value using the given mapping function and enters it into this map unless null.

如果传给该方法的key参数在Map中对应的valuenull,则使用mappingFunction根据key计算一个新的结果.

  • 如果计算结果不为null,则用计算结果覆盖原有的value
  • 如果原Map原来不包括该key,那么该方法可能会添加一组key-value对。

computeIfPresent方法

方法 描述
default V computeIfPresent(K key, BiFunction<? super K,​? super V,​? extends V> remappingFunction) If the value for the specified key is present and non-null, attempts to compute a new mapping given the key and its current mapped value.

如果传给该方法的key参数在Map中对应的 value不为null,该方法将使用remappingFunction根据原keyvalue计算一个新的结果

  • 如果计算结果不为null,则使用该结果覆盖原来的value;
  • 如果计算结果为null,则删除原key-value对;

forEach方法

方法 描述
default void forEach(BiConsumer<? super K,​? super V> action) Performs the given action for each entry in this map until all entries have been processed or the action throws an exception.

该方法是Java 8Map新增的一个遍历key-value对的方法通过该方法可以更简洁地遍历Mapkey-value对。

getOrDefault方法

方法 描述
default V getOrDefault(Object key, V defaultValue) Returns the value to which the specified key is mapped, or defaultValue if this map contains no mapping for the key.

获取指定key对应的value。如果该key不存在,则返回defaultValue.

merge方法

方法 描述
default V merge(K key, V value, BiFunction<? super V,​? super V,​? extends V> remappingFunction) If the specified key is not already associated with a value or is associated with null, associates it with the given non-null value.

该方法会先根据key参数获取该Map中对应的value

  • 如果获取的valuenull,则直接用传入的value覆盖原有的value(在这种情况下,可能要添加一组key-value对);
  • 如果获取的value不为null,则使用remappingFunction函数根据原value、新value计算一个新的结果,并用得到的结果去覆盖原有的value.

putIfAbsent方法

方法 描述
default V putIfAbsent(K key, V value) If the specified key is not already associated with a value (or is mapped to null) associates it with the given value and returns null, else returns the current value.

该方法会自动检测指定key对应的value是否为null.

  • 如果该key对应的valuenull,该方法将会用新value代替原来的null值。

replace方法

方法 描述
Object replace(Object key, Object value) Map中指定key对应的value替换成新value。与传统put()方法不同的是,该方法不可能添加新的key-value对。如果尝试替换的key在原Map中不存在,该方法不会添加key-value对,而是返回null.
boolean replace(K key,V oldValue, V newValue) Map中指定key-value对的原value替换成新value。如果在Map中找到指定的key-value对,则执行替换并返回true,否则返回false.

replaceAll方法

方法 描述
default V replace(K key, V value) Replaces the entry for the specified key only if it is currently mapped to some value.

该方法使用BiFunction对原key-value对执行计算,并将计算结果作为该key-value对的value值。

程序 Map常用默认方法测试

下面程序示范了Map常用默认方法的功能和用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.util.*;

public class MapTest2 {
public static void main(String[] args) {
Map map = new HashMap();
// 成对放入多个key-value对
map.put("疯狂Java讲义", 109);
map.put("疯狂iOS讲义", 99);
map.put("疯狂Ajax讲义", 79);
// 尝试替换key为"疯狂XML讲义"的value,由于原Map中没有对应的key,
// 因此对Map没有改变,不会添加新的key-value对
map.replace("疯狂XML讲义", 66);
System.out.println(map);
// 使用原value与参数计算出来的结果覆盖原有的value
// Object merge(Object key, Object value, BiFunction remappingFunction)`
map.merge("疯狂iOS讲义", 10, (oldVal, param) -> (Integer) oldVal + (Integer) param);
System.out.println(map); // "疯狂iOS讲义"的value增大了10
// 当key为"Java"对应的value为null(或不存在时),使用计算的结果作为新value
// Object computeIfAbsent(object key, Function mappingFunction)
map.computeIfAbsent("Java", (key) -> ((String) key).length());
System.out.println(map); // map中添加了 Java=4 这组key-value对
// 当key为"Java"对应的value存在时,使用计算的结果作为新value
// Object computeIfPresent(Object key, BiFunction remappingFunction)
map.computeIfPresent("Java", (key, value) -> (Integer) value * (Integer) value);
System.out.println(map); // map中 Java=4 变成 Java=16
}
}

运行效果:

1
2
3
4
{疯狂Ajax讲义=79, 疯狂iOS讲义=99, 疯狂Java讲义=109}
{疯狂Ajax讲义=79, 疯狂iOS讲义=109, 疯狂Java讲义=109}
{Java=4, 疯狂Ajax讲义=79, 疯狂iOS讲义=109, 疯狂Java讲义=109}
{Java=16, 疯狂Ajax讲义=79, 疯狂iOS讲义=109, 疯狂Java讲义=109}

上面程序中注释已经写得很清楚了,而且给出了每个方法的运行结果,读者可以结合这些方法的介绍文档来阅读该程序,从而掌握Map中这些默认方法的功能与用法。