getOrDefault
V getOrDefault(Object key, V defaultValue)
当 Map 中不包含指定的 key 时,返回默认值。
Map<String, String> map = new HashMap<>();
map.put("k1", null);
map.put("k2", "a");
String v1 = map.getOrDefault("k1", "v1");
String v2 = map.getOrDefault("k2", "v2");
String v3 = map.getOrDefault("k3", "v3");
System.out.println(v1);
System.out.println(v2);
System.out.println(v3);
null
a
v3
默认实现
V v;
return (((v = get(key)) != null) || containsKey(key))
? v : defaultValue;
remove
boolean remove(Object key, Object value)
仅当指定的 key 关联到指定的 value 时,才删除指定的项,删除成功返回 true。
Map<String, String> map = new HashMap<>();
map.put("k1", null);
map.put("k2", "a");
map.put("k3", "b");
map.put("k4", "");
System.out.println(map);
// value 不同,失败
boolean b1 = map.remove("k1", "a");
// value 不同,失败
boolean b2 = map.remove("k2", "b");
// value 相同,成功
boolean b3 = map.remove("k3", "b");
System.out.println(b1);
System.out.println(b2);
System.out.println(b3);
System.out.println(map);
{k1=null, k2=a, k3=b, k4=}
false
false
true
{k1=null, k2=a, k4=}
默认实现等价于
// 包含 key,且 value 相等
if (map.containsKey(key) && Objects.equals(map.get(key), value)) {
map.remove(key);
return true;
} else
return false;
putIfAbsent
V putIfAbsent(K key, V value)
当指定的 key 没有对应的 value(或对应的 value 为 null )时,执行 put 操作并返回 null,否则只返回当前的 value(不执行 put)。
Map<String, String> map = new HashMap<>();
// 没有与 key 对应的 value,返回 null
String r1 = map.putIfAbsent("k", "a");
System.out.println(map + " " + r1);
// key 已经有对应的值 a 了,没有执行 put(k, b),且返回了当前值 a
String r2 = map.putIfAbsent("k", "b");
System.out.println(map + " " + r2);
{k=a} null
{k=a} a
默认实现等价于
V v = map.get(key);
if (v == null)
v = map.put(key, value);
return v;
forEach
void forEach(BiConsumer<? super K, ? super V> action)
使用所有的键值对特定的操作。
Map<String, String> map = new HashMap<>();
map.put("k1", null);
map.put("k2", "a");
map.put("k3", "b");
map.put("k4", "");
map.forEach((k, v) -> System.out.println(k + " " + v));
k1 null
k2 a
k3 b
k4
默认实现等价于
for (Map.Entry<K, V> entry : map.entrySet())
action.accept(entry.getKey(), entry.getValue());
replace
replace(key, value)
V replace(K key, V value)
若指定的 key 存在,则用新值替换旧值。替换成功返回旧值,否则返回 null。
Map<String, String> map = new HashMap<>();
// 没有与 key 对应的 value,没有替换,返回 null
String r1 = map.replace("k", "a");
System.out.println(map + " " + r1);
map.put("k", null);
System.out.println(map);
// key 已经有对应的值 null 了,替换成功,且返回了旧值 null
String r2 = map.replace("k", "b");
System.out.println(map + " " + r2);
map.put("k", "a");
System.out.println(map);
// key 已经有对应的值 a 了,替换成功,且返回了旧值 a
String r3 = map.replace("k", "c");
System.out.println(map + " " + r3);
{} null
{k=null}
{k=b} null
{k=a}
{k=c} a
默认实现等价于
if (map.containsKey(key)) {
return map.put(key, value);
} else
return null;
replace(key, oldValue, newValue)
boolean replace(K key, V oldValue, V newValue)
只有当指定的 key 存在,且关联的值等于 oldValue 时,才用新值 newValue 替换旧值,替换成功返回 true。
Map<String, String> map = new HashMap<>();
map.put("k1", "a");
map.put("k2", "b");
System.out.println(map);
// k3 不存在,替换失败
boolean r1 = map.replace("k3", "c", "ccc");
System.out.println(map + " " + r1);
// k1 存在,但值不等于 aa,替换失败
boolean r2 = map.replace("k1", "aa", "aaa");
System.out.println(map + " " + r2);
// k2 存在,且值等于 b,替换成功
boolean r3 = map.replace("k2", "b", "bbb");
System.out.println(map + " " + r3);
{k1=a, k2=b}
{k1=a, k2=b} false
{k1=a, k2=b} false
{k1=a, k2=bbb} true
默认实现等价于
// 存在key,且value相等
if (map.containsKey(key) && Objects.equals(map.get(key), oldValue)) {
map.put(key, newValue);
return true;
} else
return false;
replaceAll
void replaceAll(BiFunction<? super K, ? super V, ? extends V> function)
使用传入的 function 重新计算所有的 value
Map<String, String> map = new HashMap<>();
map.put("k1", null);
map.put("k2", "a");
map.put("k3", "b");
map.put("k4", "");
System.out.println(map);
map.replaceAll((k, v)-> k + v);
System.out.println(map);
{k1=null, k2=a, k3=b, k4=}
{k1=k1null, k2=k2a, k3=k3b, k4=k4}
默认实现等价于
for (Map.Entry<K, V> entry : map.entrySet())
entry.setValue(function.apply(entry.getKey(), entry.getValue()));
computeIfAbsent
V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)
// mappingFunction 的参数是 key,返回值是 value
如果指定的 key 不存在(或关联的 value 为 null),则使用给定的 function 计算 value 并执行 put(只有计算出的 value 不为 null 才 put),总是返回当前的最新值(已存在的或刚刚计算出来的)。最常见的用法是构造一个新对象作为初始映射值:map.computeIfAbsent(key, k -> new Value(f(k)));
或者实现一个多值(multi-value)Map, Map<K,Collection<V>>
,支持每个键多个值:map.computeIfAbsent(key, k -> new HashSet<V>()).add(v);
。
Map<String, String> map = new HashMap<>();
map.put("k2", null);
map.put("k3", "c");
System.out.println(map);
// k1 不存在,执行 put
String v1 = map.computeIfAbsent("k1", (k) -> k + k);
// k2 存在,但值为null,执行 put
String v2 = map.computeIfAbsent("k2", (k) -> k + k);
// k3 存在,但值不为null,不执行 put
String v3 = map.computeIfAbsent("k3", (k) -> k + k);
// k4 不存在,但计算结果为 null,不执行 put
String v4 = map.computeIfAbsent("k4", (k) -> null);
System.out.println(v1);
System.out.println(v2);
System.out.println(v3);
System.out.println(v4);
System.out.println(map);
{k2=null, k3=c}
k1k1
k2k2
c
null
{k1=k1k1, k2=k2k2, k3=c}
实现一个ArrayListMultiMap
public class ArrayListMultiMap<K, V> {
private final Map<K, ArrayList<V>> map;
public ArrayListMultiMap() {
map = new HashMap<>();
}
public void put(K key, V value) {
map.computeIfAbsent(key, (k) -> new ArrayList<>()).add(value);
}
public ArrayList<V> get(K key) {
return map.get(key);
}
@Override
public String toString() {
return "ArrayListMultiMap{" +
"map=" + map +
'}';
}
public static void main(String[] args) {
ArrayListMultiMap<String, String> multiMap = new ArrayListMultiMap<>();
multiMap.put("k1", "a");
multiMap.put("k1", "b");
multiMap.put("k1", "a");
multiMap.put("k1", "c");
multiMap.put("k2", "aa");
multiMap.put("k2", "bb");
System.out.println(multiMap);
}
}
ArrayListMultiMap{map={k1=[a, b, a, c], k2=[aa, bb]}}
默认实现
default V computeIfAbsent(K key,
Function<? super K, ? extends V> mappingFunction) {
Objects.requireNonNull(mappingFunction);
V v;
// key 没有关联的 value
if ((v = get(key)) == null) {
V newValue;
// 计算出的 value 不为 null
if ((newValue = mappingFunction.apply(key)) != null) {
put(key, newValue);
return newValue;
}
}
return v;
}
computeIfPresent
V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)
// remappingFunction 的参数是(key, oldValue),返回值是 newValue
仅当指定 key 关联的 value 存在且非 null 时,使用给定的 function 计算新的 value。如果 function 的返回值为 null,则执行删除,返回最新的值或 null(key 不存在或 value 为 null ,或 function 的结果为 null 时)。
Map<String, String> map = new HashMap<>();
map.put("k1", "a");
map.put("k3", null);
map.put("k4", "d");
System.out.println(map);
// k1 存在且值不为 null,执行 put
String v1 = map.computeIfPresent("k1", (k, v) -> k + v);
// k2 不存在,不执行 put
String v2 = map.computeIfPresent("k2", (k, v) -> k + v);
// k3 存在,但值为null,不执行 put
String v3 = map.computeIfPresent("k3", (k, v) -> k + v);
// k4 存在,但计算结果为 null,不执行 put
String v4 = map.computeIfPresent("k4", (k, v) -> null);
System.out.println(v1);
System.out.println(v2);
System.out.println(v3);
System.out.println(v4);
System.out.println(map);
{k1=a, k3=null, k4=d}
k1a
null
null
null
{k1=k1a, k3=null}
默认实现
default V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
V oldValue;
// key 关联的 value 存在且不为 null
if ((oldValue = get(key)) != null) {
V newValue = remappingFunction.apply(key, oldValue);
// 计算结果不为 null,执行 put
if (newValue != null) {
put(key, newValue);
return newValue;
// 计算结果为 null,执行删除
} else {
remove(key);
return null;
}
} else {
return null;
}
}
compute
V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)
// remappingFunction 的参数是(key, oldValue),返回值是 newValue
使用 function 计算 value,若 value 不为 null,执行 put,否则执行删除。返回最新的值,或 null(function 返回值为 null 时)。
Map<String, String> map = new HashMap<>();
map.put("k1", "a");
map.put("k3", null);
map.put("k4", "d");
System.out.println(map);
// function 返回值不为 null,执行 put
String v1 = map.compute("k1", (k, v) -> k + v);
// function 返回值不为 null,执行 put
String v2 = map.compute("k2", (k, v) -> k + v);
// function 返回值不为 null,执行 put
String v3 = map.compute("k3", (k, v) -> k + v);
// function 返回值为 null,执行删除
String v4 = map.compute("k4", (k, v) -> null);
System.out.println(v1);
System.out.println(v2);
System.out.println(v3);
System.out.println(v4);
System.out.println(map);
{k1=a, k3=null, k4=d}
k1a
k2null
k3null
null
{k1=k1a, k2=k2null, k3=k3null}
默认实现
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);
// 新值为 null
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 {
// 新值不为 null 插入或更新
// add or replace old mapping
put(key, newValue);
return newValue;
}
}
merge
V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction)
// remappingFunction 的参数(oldValue, paramValue),返回值 newValue
如果指定的 key 不存在(或关联的 value 为 null),则使用给定的 value 执行 put。否则使用给定的 function 计算 value 并执行 put(function 返回值 为 null 时会执行删除)。当需要组合同一个 key 的多个 value 时很有用,比如创建或追加 msg 到 value:map.merge(key, msg, String::concat)
Map<String, String> map = new HashMap<>();
map.put("k2", null);
map.put("k3", "c");
map.put("k4", "d");
System.out.println(map);
// k1 不存在,执行 put
String v1 = map.merge("k1", "a", String::concat);
// k2 存在但值为 null,执行 put
String v2 = map.merge("k2", "b", String::concat);
// k3 存在,执行 merge
String v3 = map.merge("k3", "-c", String::concat);
// k4 存在,但 function 返回值为 null,执行 删除
String v4 = map.merge("k4", "c", (oldValue, value) -> null);
System.out.println(v1);
System.out.println(v2);
System.out.println(v3);
System.out.println(v4);
System.out.println(map);
{k2=null, k3=c, k4=d}
a
b
c-c
null
{k1=a, k2=b, k3=c-c}
默认实现
default V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
// 指定的 value 不能为 null
Objects.requireNonNull(value);
V oldValue = get(key);
// 旧值不存在,则使用给定 value 执行 put
// 旧值存在,则使用 Function 计算新值
V newValue = (oldValue == null) ? value : remappingFunction.apply(oldValue, value);
// Function 返回值为 null,执行删除
if(newValue == null) {
remove(key);
} else {
put(key, newValue);
}
return newValue;
}