接口Map是用来取代较早版本的Dictionary的,如上图接口中定义了一些对Map的常规操作,下面介绍阅读代码比较有意思的几个地方:
1.如果没有默认值,就返回设置的defalutvalue
default V getOrDefault(Object key, V defaultValue) {
V v;
return (((v = get(key)) != null) || containsKey(key))
? v : defaultValue;
}
2.forEach是map用来进行Lambda式遍历操作的。可以看到参数是一个函数式接口action,通过函数式编程可以实现对map中所有entry的遍历
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);
}
}
3.replaceAll使用了可以传递3个参数的内置的函数式接口BiFunction,其方法apply方法可以返回一个继承至V的值,可以看到这个方法时通过function处理K,V之后,处理方法是针对其父类的(? super K),然后得到新的值赋值给之前的key。
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);
}
}
}
4.merge方法用来合并的,如果key有值,则通过remappingFunction方法处理新老值替换掉之前的值,如果没值就用value代替,如果value是null 或者处理后的新值时null的,则删除这个key
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;
}
网友评论