持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情
默认方法
public interface Map<K,V> {
// Defaultable methods
default V getOrDefault(Object key, V defaultValue) {
V v;
return (((v = get(key)) != null) || containsKey(key))
? v
: defaultValue;
}
default void forEach(BiConsumer<? super K, ? super V> action) {
Objects.requireNonNull(action);
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);
}
action.accept(k, v);
}
}
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);
}
}
}
default V putIfAbsent(K key, V value) {
V v = get(key);
if (v == null) {
v = put(key, value);
}
return v;
}
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;
}
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;
}
default V replace(K key, V value) {
V curValue;
if (((curValue = get(key)) != null) || containsKey(key)) {
curValue = put(key, value);
}
return curValue;
}
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;
}
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;
}
}
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;
}
}
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;
}
}
复制代码
default V getOrDefault(Object key, V defaultValue)
:返回指定 key 映射的 value,如果这个 map 不包含 key 的映射,则返回默认值- 默认实现不保证这个方法的同步或者原子属性。任何提供原子保证的实现必须重写这个方法并且记录他的并发属性
default void forEach(BiConsumer<? super K, ? super V> action)
:对这个 map 每个 entry 执行指定的操作,直到全部 entry 已经被处理完或者操作抛出异常。除非实现类另外指定,否则操作按照 entry set 迭代顺序执行(如果指定迭代顺序)- 默认实现等效于
for (Map.Entry<K, V> entry : map.entrySet()) action.accept(entry.getKey(), entry.getValue()); 复制代码
- 默认实现不保证这个方法的同步或者原子属性。任何提供原子保证的实现必须重写这个方法并且记录他的并发属性
default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function)
:通过对 entry 调用给定方法的结果替换每个 entry 的 value,直到处理完全部 entry 或者函数抛出异常,函数抛出的异常以被转发到调用方- 默认实现等效于
for (Map.Entry<K, V> entry : map.entrySet()) entry.setValue(function.apply(entry.getKey(), entry.getValue())); 复制代码
- 默认实现不保证这个方法的同步或者原子属性。任何提供原子保证的实现必须重写这个方法并且记录他的并发属性
default V putIfAbsent(K key, V value)
:如果指定 key 没已经关联 value(或映射 null),通过给定 value 关联它,并且返回 null,否则返回当前 value- 默认实现等效于
V v = map.get(key); if (v == null) v = map.put(key, value); return v; 复制代码
- 默认实现不保证这个方法的同步或者原子属性。任何提供原子保证的实现必须重写这个方法并且记录他的并发属性
default boolean remove(Object key, Object value)
:只有当指定 key 当前映射指定 value,才移除指定 key 的 entry- 默认实现等效于
if (map.containsKey(key) && Objects.equals(map.get(key), value)) { map.remove(key); return true; } else return false; 复制代码
- 默认实现不保证这个方法的同步或者原子属性。任何提供原子保证的实现必须重写这个方法并且记录他的并发属性
default boolean replace(K key, V oldValue, V newValue)
:只有当当前映射到指定 value,才替换指定 key 的 entry- 默认实现等效于
if (map.containsKey(key) && Objects.equals(map.get(key), value)) { map.put(key, newValue); return true; } else return false; 复制代码
- 如果旧值是 null,默认实现不会因为 map 不支持 null 值抛 NullPointerException,除非新值同样是 null
- 默认实现不保证这个方法的同步或者原子属性。任何提供原子保证的实现必须重写这个方法并且记录他的并发属性
default V replace(K key, V value)
:替换指定 key 的 entry,当且仅当 key 当前映射一些 value- 默认实现等效于
if (map.containsKey(key)) { return map.put(key, value); } else return null; 复制代码
- 默认实现不保证这个方法的同步或者原子属性。任何提供原子保证的实现必须重写这个方法并且记录他的并发属性
default V computeIfAbsent(K key,Function<? super K, ? extends V> mappingFunction)
:如果指定 key 没有和 value 真正关联(或者映射 null),尝试使用给定映射函数去完成它的 value,并且输入它的映射,除非 null- 如果函数返回 null,则不记录映射。如果函数它自己抛出一个(未检测)异常,异常被抛出,并且不记录映射。最常见的用法是构造一个新对象作为初始化映射 value 或记录结果,如:map.computeIfAbsent(key, k -> new Value(f(k)));
- 或者实现多值映射,Map<K,Collection>,支持每个 key 多 value: map.computeIfAbsent(key, k -> new HashSet()).add(v);
- 默认实现等效于这个 map 执行下面步骤,然后返回当前值,如果现在不存在,返回 null
if (map.get(key) == null) { V newValue = mappingFunction.apply(key); if (newValue != null) map.put(key, newValue); } 复制代码
- 默认实现不保证这个方法的同步或者原子属性。任何提供原子保证的实现必须重写这个方法并且记录他的并发属性
- 贴别是,子接口 ConcurrentMap 的全部实现必须记录函数是否只有当 value 不存在时以原子方式应用一次
default V computeIfPresent(K key,BiFunction<? super K, ? super V, ? extends V> remappingFunction)
:如果指定 key 的 value 存在并且 non-null,尝试在给定 key 和它当前映射 value 下去完成一个新映射- 如果函数返回 null,映射被移除。如果函数本身抛出(未检测)异常,异常被重新抛出,并且当前映射保持不变
- 默认实现等效于这个 map 执行下列步骤,然后返回当前 value,如果现在不存在,返回 null
if (map.get(key) != null) { V oldValue = map.get(key); V newValue = remappingFunction.apply(key, oldValue); if (newValue != null) map.put(key, newValue); else map.remove(key); } 复制代码
- 默认实现不保证这个方法的同步或者原子属性。任何提供原子保证的实现必须重写这个方法并且记录他的并发属性
- 贴别是,子接口 ConcurrentMap 的全部实现必须记录函数是否只有当 value 不存在时以原子方式应用一次
default V compute(K key,BiFunction<? super K, ? super V, ? extends V> remappingFunction)
:尝试计算指定 key 和它当前映射值(如果当前没有映射,为 null)的映射。例如,创建或附加 String 消息到 value 映射map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg))
(方法 merge 对这种目的经常更容易使用)- 如果函数返回 null,映射被移除(或者初始化缺少时依然缺少)。如果函数它自己抛出(未检测)异常,异常被重新抛出,并且当前映射保持不变
- 默认实现等效于对这个 map 执行下面步骤,然后返回当前值,如果不存在,返回 null
V oldValue = map.get(key); V newValue = remappingFunction.apply(key, oldValue); if (oldValue != null ) { if (newValue != null) map.put(key, newValue); else map.remove(key); } else { if (newValue != null) map.put(key, newValue); else return null; } 复制代码
- 默认实现不保证这个方法的同步或者原子属性。任何提供原子保证的实现必须重写这个方法并且记录他的并发属性
- 贴别是,子接口 ConcurrentMap 的全部实现必须记录函数是否只有当 value 不存在时以原子方式应用一次
default V merge(K key, V value,BiFunction<? super V, ? super V, ? extends V> remappingFunction)
:如果指定 key 没有真正与 value 关联,或者关联 null,关联它通过给定 non-null value。否则,通过给定映射方法的结果替代关联的值,或者如果结果是 null 则移除。当 key 组合多个映射 value,可以使用这方法。例如,创建或者附加 msg 到 value 映射:map.merge(key, msg, String::concat)
- 如果函数返回 null,映射被移除。如果函数它自己抛出(未检测)异常,异常被重新抛出,并且当前映射保持不变
- 默认实现等效于对这个 map 执行下面步骤,然后返回当前值,如果不存在,返回 null
V oldValue = map.get(key); V newValue = (oldValue == null) ? value : remappingFunction.apply(oldValue, value); if (newValue == null) map.remove(key); else map.put(key, newValue); 复制代码
- 默认实现不保证这个方法的同步或者原子属性。任何提供原子保证的实现必须重写这个方法并且记录他的并发属性
- 贴别是,子接口 ConcurrentMap 的全部实现必须记录函数是否只有当 value 不存在时以原子方式应用一次