目录
简介
查询 size,isEmpty,containsKey,containsValue
对key的增删改查 get,put,remove
批量操作 putAll,clear
Entry接口
简介
对key和value的操作 getKey,setValue,getValue
equals,hashcode
返回comparator comparingByKey两个,comparingByValue
视图 keySet,values,entrySet
equals,hashCode
批量操作 forEach,replaceAll
单个操作 getOrDefault,putIfAbsent,remove,两个replace
三个computeXXX,merge
/**
* 一个对象,将键映射到值(key to value)。
* 一个map不能包含重复的key,每个key仅仅能映射到最大一个值。
*
*
这个接口替代了Dictionary类,那是一个纯粹的抽象类而不是一个接口。
*
*
Map接口提供了三个集合视图,允许一个map的内容能被看做一个key的set,
* 一个value的collection,或者key-value映射的set。
* map的顺序为map的视图集合的迭代器返回元素的顺序。
* 一些map的实现,像TreeMap类,对顺序做出特定的保证,一些,像HashMap类,没有保证顺序。
*
*
注意:必须小心,如果可变的对象被用作map的key。
* 如果一个对象是map的key,而对象被改变了,影响equals的比较,map的行为没有被指定。
* 一个禁止的特殊情况是不允许map把自己作为一个key。
* 虽然允许map把自己作为一个value,但要告警:
* equals和hashCode方法在这种map上,定义的不好。
*
*
所有的通常目的的map实现类应该提供两个标准的构造器,一个无参构造器,创建一个空的map,
* 一个有着单一参数Map类型的构造器,创建一个新的map,有着与它的参数相同的key-value映射。
* 实际上,后一个构造器允许使用者复制任何map,参数一个需要的类的相同的map。
* 没有方法强制这个建议(因为接口不能包含构造器),但是所有的通常目的的JDK中的map实现遵循它。
*
*
这个接口中包含破坏性的方法,那是如果map不支持某种修改操作,抛出UnsupportedOperationException。
* 如果是这种情况,如果调用对map无效,这些方法可以,但不必要,抛出UnsupportedOperationException。
* 例如,在一个不可更改的map中调用putAll(Map)方法,可以,但不必要,
* 抛出异常,如果要叠加的map的映射为空。
*
*
一些map实现对可以包含的key和value有限制。
* 例如一些实现禁止null的key和value,一些对key的类型有限制。
* 视图插入一个非法的key或value会抛出未检查异常,通常是NullPointerException,ClassCastException。
* 视图查询一个非法的key或value可以抛出一个异常,或者仅仅返回false。
* 一些实现会实现前面的行为,一些会实现后面的行为。
* 更一般地说,尝试对不符合条件的元素执行操作,而该元素的完成不会导致将不符合条件的元素插入到set中,这可能会引发异常,
* 也可能会成功,取决于实现的选择。在这个接口的规范中,这些异常被标记为“可选”。
*
*
集合框架接口的许多方法根据equals方法定义。
* 例如containsKey(Object)方法说:返回true,当且仅当map包含一个这样的key,
* (key==null ? k==null : key.equals(k))。
* 这个规范不应该解释为调用使用一个非null参数,调用Map.containsKey,会导致任意的键key调用key.equals(k)。
* 实现可以自由的进行优化,从而避免调用equals。
* 例如,一开始比较两个key的hashCode(hashCode的规范保证两个有着不相同的hashcode的对象,一定不相等)。
* 更一般的说,集合框架接口的实现能在它觉得合适的地方,自由的利用Object的底层行为。
*
*
一些map的循环遍历操作可能失败,到map直接或间接拥有自己。
* 这包括clone()、equals()、hashCode()和toString()方法。
* 实现可以额外地处理自引用的场景,仅仅大多数目前的实现没有这样做。
*
* @param the type of keys maintained by this map
* @param the type of mapped values
*
* @author Josh Bloch
* @see HashMap
* @see TreeMap
* @see Hashtable
* @see SortedMap
* @see Collection
* @see Set
* @since 1.2
*/
public interface Map
// Query Operations
/**
* 返回map中key-value对的数量。如果map包含超过Integer.MAX_VALUE的元素,返回Integer.MAX_VALUE
*
* @return the number of key-value mappings in this map
*/
int size();
/**
* 如果map不包含任何key-value对,返回true
*
* @return true if this map contains no key-value mappings
*/
boolean isEmpty();
/**
* 如果map包含有着指定的key的映射,返回true。
* 更正式地,当且仅当map有一个有着这样的key k的映射时,返回true。
* (key==null ? k==null : key.equals(k)).
* (最多只能有一个这样的映射)
*
* @param key key whose presence in this map is to be tested
* @return true if this map contains a mapping for the specified
* key
* @throws ClassCastException if the key is of an inappropriate type for
* this map
* (optional)
* @throws NullPointerException if the specified key is null and this map
* does not permit null keys
* (optional)
*/
boolean containsKey(Object key);
/**
* 如果map包含有着一个或多个指定的value的映射,返回true。
* 更正式地,当且仅当map有一个或多个有着这样的value v的映射时,返回true。
* (value==null ? v==null : value.equals(v)).
* 这个操作可能会需要与map的大小,线性的时间,对于大多数Map接口的实现。
*
* @param value value whose presence in this map is to be tested
* @return true if this map maps one or more keys to the
* specified value
* @throws ClassCastException if the value is of an inappropriate type for
* this map
* (optional)
* @throws NullPointerException if the specified value is null and this
* map does not permit null values
* (optional)
*/
boolean containsValue(Object value);
/**
* 得到指定key映射的value,或者如果map不包含key对于的映射,返回null
*
* 更正式地,如果map包含一个这样的映射,里面的key k 和value v是这样的
* {@code (key==null ? k==null :key.equals(k))} ,那么方法返回v。
* 否则,返回null。(里面最多一个这样的映射)
*
*
如果这个map允许null值,那么返回null,不一定表明map不包含这个key对应的映射。
* 也可能key对应的值为null。
* containsKey操作可以用于辨明这两种情况。
*
* @param key the key whose associated value is to be returned
* @return the value to which the specified key is mapped, or
* {@code null} if this map contains no mapping for the key
* @throws ClassCastException if the key is of an inappropriate type for
* this map
* (optional)
* @throws NullPointerException if the specified key is null and this map
* does not permit null keys
* (optional)
*/
V get(Object key);
// Modification Operations
/**
* 将指定的key与指定的value在这个map中关联(可选操作)。
* 如果map之前包含了这个key的映射,旧的value被指定value替代。
* (一个map m 被认为包含一个key k ,当且仅当m.containsKey(k) 返回true。
*
* @param key key with which the specified value is to be associated
* @param value value to be associated with the specified key
* @return the previous value associated with key, or
* null if there was no mapping for key.
* (A null return can also indicate that the map
* previously associated null with key,
* if the implementation supports null values.)
* @throws UnsupportedOperationException if the put operation
* is not supported by this map
* @throws ClassCastException if the class of the specified key or value
* prevents it from being stored in this map
* @throws NullPointerException if the specified key or value is null
* and this map does not permit null keys or values
* @throws IllegalArgumentException if some property of the specified key
* or value prevents it from being stored in this map
*/
V put(K key, V value);
/**
* 将map中key对应的映射移除,如果映射存在(可选操作)。
* 更正式的,如果map包含一个这样的映射,里面的key k 和value v是这样的
* {@code (key==null ? k==null :key.equals(k))} ,那么映射被删除。
* (一个map只能包含最多一个这样的映射)
*
*
返回map之前与key关联的value,或者如果map不包含key对应的映射,返回null。
*
*
如果这个map允许null值,那么返回null,不一定表明map不包含这个key对应的映射。
* 也可能key对应的值为null。
*
*
一旦调用返回,map不会有指定key对应的映射。
*
* @param key key whose mapping is to be removed from the map
* @return the previous value associated with key, or
* null if there was no mapping for key.
* @throws UnsupportedOperationException if the remove operation
* is not supported by this map
* @throws ClassCastException if the key is of an inappropriate type for
* this map
* (optional)
* @throws NullPointerException if the specified key is null and this
* map does not permit null keys
* (optional)
*/
V remove(Object key);
// Bulk Operations
/**
* 复制指定map,所有的映射,到这个map(可选操作)
* 这个调用的结果与对指定map的每个映射的key k和value v,对这个map调用put(k, v)。
* 如果指定map被修改,同时正在执行这个操作,操作的结果没有被定义。
*
* @param m mappings to be stored in this map
* @throws UnsupportedOperationException if the putAll operation
* is not supported by this map
* @throws ClassCastException if the class of a key or value in the
* specified map prevents it from being stored in this map
* @throws NullPointerException if the specified map is null, or if
* this map does not permit null keys or values, and the
* specified map contains null keys or values
* @throws IllegalArgumentException if some property of a key or value in
* the specified map prevents it from being stored in this map
*/
void putAll(Map extends K, ? extends V> m);
/**
* 删除map中所有的映射(可选操作)。
* 调用返回后,map为空。
*
* @throws UnsupportedOperationException if the clear operation
* is not supported by this map
*/
void clear();
/**
* 一个map的entry。(key-value对)。
* Map.entrySet方法返回map的一个collection视图,里面的元素是这个类。
* 唯一获得一个map entry的引用的方法是从这个collection视图的迭代器获得。
* 更正式的,一个map entry的行为是未知的,如果在Iterator返回entry后,依赖的map被改变,
* 除非对entry使用setValue操作。
*
* @see Map#entrySet()
* @since 1.2
*/
interface Entry
/**
* 返回这个entry对应的key
*
* @return the key corresponding to this entry
* @throws IllegalStateException implementations may, but are not
* required to, throw this exception if the entry has been
* removed from the backing map.
*/
K getKey();
/**
* 返回这个entry对应的value。
* 如果映射被依赖的map删除了(通过Iterator的remove方法),这次调用的结果未知。
*
* @return the value corresponding to this entry
* @throws IllegalStateException implementations may, but are not
* required to, throw this exception if the entry has been
* removed from the backing map.
*/
V getValue();
/**
* 将entry的value替代为指定的value(可选操作)(写入map)
* 这个调用的行为未知,如果映射已经被map删除(通过Iterator的remove方法)
*
* @param value new value to be stored in this entry
* @return old value corresponding to the entry
* @throws UnsupportedOperationException if the put operation
* is not supported by the backing map
* @throws ClassCastException if the class of the specified value
* prevents it from being stored in the backing map
* @throws NullPointerException if the backing map does not permit
* null values, and the specified value is null
* @throws IllegalArgumentException if some property of this value
* prevents it from being stored in the backing map
* @throws IllegalStateException implementations may, but are not
* required to, throw this exception if the entry has been
* removed from the backing map.
*/
V setValue(V value);
/**
* 将指定对象与这个entry进行相等性的比较。
* 如果给定的对象也是一个map的entry,两个entry代表同样的映射,返回true。
* 更正式地,两个entry e1和e2代表同样的映射,如果(key相同,value相同):
*
* (e1.getKey()==null ?
* e2.getKey()==null : e1.getKey().equals(e2.getKey())) &&
* (e1.getValue()==null ?
* e2.getValue()==null : e1.getValue().equals(e2.getValue()))
*
* 这保证equals方法在不同的Map.Entry接口的实现间,工作正常。
*
* @param o object to be compared for equality with this map entry
* @return true if the specified object is equal to this map
* entry
*/
boolean equals(Object o);
/**
* 返回这个map entry的hashcode。hashcode安装如下定义(key和value的hashcode进行亦或):
*
* (e.getKey()==null ? 0 : e.getKey().hashCode()) ^
* (e.getValue()==null ? 0 : e.getValue().hashCode())
*
* 这保证e1.equals(e2)代表e1.hashCode()==e2.hashCode(),
* 对于任何两个entry e1和e2,按照Object的hashCode的要求
*
* @return the hash code value for this map entry
* @see Object#hashCode()
* @see Object#equals(Object)
* @see #equals(Object)
*/
int hashCode();
/**
* 返回一个comparator,根据key的自然顺序,对 Map.Entry进行比较
*
* 返回的comparator是可序列化的,当比较一个有着null的key的entry时,抛出NullPointerException
*
* @param the {@link Comparable} type of then map keys
* @param the type of the map values
* @return a comparator that compares {@link Map.Entry} in natural order on key.
* @see Comparable
* @since 1.8
*/
public static , V> Comparator> comparingByKey() {
return (Comparator> & Serializable)
(c1, c2) -> c1.getKey().compareTo(c2.getKey()); // 根据key比较
}
/**
* 返回一个comparator,根据value的自然顺序,对 Map.Entry进行比较
*
* 返回的comparator是可序列化的,当比较一个有着null的value的entry时,抛出NullPointerException
*
* @param the type of the map keys
* @param the {@link Comparable} type of the map values
* @return a comparator that compares {@link Map.Entry} in natural order on value.
* @see Comparable
* @since 1.8
*/
public static > Comparator> comparingByValue() {
return (Comparator> & Serializable)
(c1, c2) -> c1.getValue().compareTo(c2.getValue());
}
/**
* 返回一个comparator,使用给定的comparator对key进行排序,来对 Map.Entry进行比较
*
* 返回的comparator是可序列化的,如果指定的comparator也是可序列化的
*
* @param the type of the map keys
* @param the type of the map values
* @param cmp the key {@link Comparator}
* @return a comparator that compares {@link Map.Entry} by the key.
* @since 1.8
*/
public static Comparator> comparingByKey(Comparator super K> cmp) {
Objects.requireNonNull(cmp);
return (Comparator> & Serializable)
(c1, c2) -> cmp.compare(c1.getKey(), c2.getKey());
}
/**
* 返回一个comparator,使用给定的comparator对value进行排序,来对 Map.Entry进行比较
*
* 返回的comparator是可序列化的,如果指定的comparator也是可序列化的
*
* @param the type of the map keys
* @param the type of the map values
* @param cmp the value {@link Comparator}
* @return a comparator that compares {@link Map.Entry} by the value.
* @since 1.8
*/
public static Comparator> comparingByValue(Comparator super V> cmp) {
Objects.requireNonNull(cmp);
return (Comparator> & Serializable)
(c1, c2) -> cmp.compare(c1.getValue(), c2.getValue());
}
// Views
/**
* 返回这个map中包含的key的set视图。
* set由map支持,所以对map的改变会反映到set中,反之亦然。
* 如果map被修改,同时set的迭代正在进行(除了通过Iterator自己的remove操作),迭代的结果未知。
* set支持元素的删除,会导致map中对应的映射被删除,通过Iterator.remove,Set.remove,
* removeAll,retainAll,clear操作。
* set不支持add或者addAll操作。
*
* @return a set view of the keys contained in this map
*/
Set keySet();
/**
* 返回这个map中包含的value的collection视图。
* collection由map支持,所以对map的改变会反映到collection中,反之亦然。
* 如果map被修改,同时collection的迭代正在进行(除了通过Iterator自己的remove操作),迭代的结果未知。
* collection支持元素的删除,会导致map中对应的映射被删除,通过Iterator.remove,collection.remove,
* removeAll,retainAll,clear操作。
* collection不支持add或者addAll操作。
*
* @return a collection view of the values contained in this map
*/
Collection values();
/**
* 返回这个map中包含的映射的set视图。
* set由map支持,所以对map的改变会反映到set中,反之亦然。
* 如果map被修改,同时set的迭代正在进行(除了通过Iterator自己的remove操作),迭代的结果未知。
* set支持元素的删除,会导致map中对应的映射被删除,通过Iterator.remove,Set.remove,
* removeAll,retainAll,clear操作。
* set不支持add或者addAll操作。
*
* @return a set view of the mappings contained in this map
*/
Set> entrySet();
/**
* 将指定对象与这个map进行相等性的比较。
* 如果指定对象也是一个map,两个map代表相同的映射,返回true。
* 更正式地,两个map m1和m2代表相同的映射,如果m1.entrySet().equals(m2.entrySet())。
* 这保证equals方法在不同的Map接口的实现间工作正常。
*
* @param o object to be compared for equality with this map
* @return true if the specified object is equal to this map
*/
boolean equals(Object o);
/**
* 返回map的hashcode。
* map的hashcode根据map的entrySet()视图的每个entry的hashcode的和定义。
* 这保证对于任意两个map m1和m2,m1.equals(m2)代表m1.hashCode()==m2.hashCode(),
* 根据Object.hashCode的通常约定。
*
* @return the hash code value for this map
* @see Map.Entry#hashCode()
* @see Object#equals(Object)
* @see #equals(Object)
*/
int hashCode();
/**
* 对map的每个entry执行给定的操作,直到所有的entry都被处理或者一个action抛出异常。
* 除非被实现类指定,action以entry set的迭代顺序执行。(如果迭代顺序被指定)。
* action抛出的异常传递给调用者。
*
* 对于这个map,默认的实现与下面相同:
* {@code
* for (Map.Entry entry : map.entrySet())
* action.accept(entry.getKey(), entry.getValue());
* }
*
* 默认的实现不保证方法的同步性或者原子性。
* 任何提供了原子性的实现,必须覆盖这个方法,并且报告它的并发属性。
*
* @param action The action to be performed for each entry
* @throws NullPointerException if the specified action is null
* @throws ConcurrentModificationException if an entry is found to be
* removed during iteration
* @since 1.8
*/
default void forEach(BiConsumer super K, ? super V> action) {
Objects.requireNonNull(action);
for (Map.Entry entry : entrySet()) { // 对map的entrySet进行迭代
K k;
V v;
try {
k = entry.getKey();
v = entry.getValue();
} catch(IllegalStateException ise) {
// 这通常意味着这个entry已经不在map中
throw new ConcurrentModificationException(ise);
}
action.accept(k, v);
}
}
/**
* Replaces each entry's value with the result of invoking the given
* function on that entry until all entries have been processed or the
* function throws an exception. Exceptions thrown by the function are
* relayed to the caller.
*
* 将每个entry的value使用给定的程序进行替代,直到所有的entry都被处理或者一个action抛出异常。
* 除非被实现类指定,action以entry set的迭代顺序执行。(如果迭代顺序被指定)。
* action抛出的异常传递给调用者。
*
* 对于这个map,默认的实现与下面相同:
*
{@code
* for (Map.Entry entry : map.entrySet())
* entry.setValue(function.apply(entry.getKey(), entry.getValue()));
* }
*
* 默认的实现不保证方法的同步性或者原子性。
* 任何提供了原子性的实现,必须覆盖这个方法,并且报告它的并发属性。
*
* @param function the function to apply to each entry
* @throws UnsupportedOperationException if the {@code set} operation
* is not supported by this map's entry set iterator.
* @throws ClassCastException if the class of a replacement value
* prevents it from being stored in this map
* @throws NullPointerException if the specified function is null, or the
* specified replacement value is null, and this map does not permit null
* values
* @throws ClassCastException if a replacement value is of an inappropriate
* type for this map
* (optional)
* @throws NullPointerException if function or a replacement value is null,
* and this map does not permit null keys or values
* (optional)
* @throws IllegalArgumentException if some property of a replacement value
* prevents it from being stored in this map
* (optional)
* @throws ConcurrentModificationException if an entry is found to be
* removed during iteration
* @since 1.8
*/
default void replaceAll(BiFunction super K, ? super V, ? extends V> function) {
Objects.requireNonNull(function);
for (Map.Entry 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);
}
}
}
/**
* 返回指定的key映射的value,或者如果map不包含这个key对应的映射,返回defaultValue
*
*
默认的实现不保证任何这个方法的同步或者原子性。
* 任何提供了原子性的实现,必须覆盖这个方法,并且报告它的并发属性。
*
* @param key the key whose associated value is to be returned
* @param defaultValue the default mapping of the key
* @return the value to which the specified key is mapped, or
* {@code defaultValue} if this map contains no mapping for the key
* @throws ClassCastException if the key is of an inappropriate type for
* this map
* (optional)
* @throws NullPointerException if the specified key is null and this map
* does not permit null keys
* (optional)
* @since 1.8
*/
default V getOrDefault(Object key, V defaultValue) {
V v;
return (((v = get(key)) != null) || containsKey(key))
// get(key)为null有两种情况,value为null或者没有key,所以检验是否有这个key
// get(key)不为null,返回v
// get(key)为null,如果有这个key,返回v,即null
// get(key)为null,没有这个key,返回defaultValue
? v
: defaultValue;
}
/**
* 如果指定的key没有与value关联(或者映射到null),用给定的value与它关联,并返回null,
* 否则返回当前的value。
*
* 对于这个map,默认的实现与下面相同:
*
*
{@code
* V v = map.get(key);
* if (v == null)
* v = map.put(key, value);
*
* return v;
* }
*
* 默认的实现不保证方法的同步性或者原子性。
* 任何提供了原子性的实现,必须覆盖这个方法,并且报告它的并发属性。
*
* @param key key with which the specified value is to be associated
* @param value value to be associated with the specified key
* @return the previous value associated with the specified key, or
* {@code null} if there was no mapping for the key.
* (A {@code null} return can also indicate that the map
* previously associated {@code null} with the key,
* if the implementation supports null values.)
* @throws UnsupportedOperationException if the {@code put} operation
* is not supported by this map
* (optional)
* @throws ClassCastException if the key or value is of an inappropriate
* type for this map
* (optional)
* @throws NullPointerException if the specified key or value is null,
* and this map does not permit null keys or values
* (optional)
* @throws IllegalArgumentException if some property of the specified key
* or value prevents it from being stored in this map
* (optional)
* @since 1.8
*/
default V putIfAbsent(K key, V value) {
V v = get(key);
if (v == null) { // value为null或者key不存在
v = put(key, value);
}
return v;
}
/**
* 将指定key对应的entry删除,当且仅当指定的key映射到指定的value
*
*
对于这个map,默认的实现与下面相同:
*
*
{@code
* if (map.containsKey(key) && Objects.equals(map.get(key), value)) {
* map.remove(key);
* return true;
* } else
* return false;
* }
*
* 默认的实现不保证方法的同步性或者原子性。
* 任何提供了原子性的实现,必须覆盖这个方法,并且报告它的并发属性。
*
* @param key key with which the specified value is associated
* @param value value expected to be associated with the specified key
* @return {@code true} if the value was removed
* @throws UnsupportedOperationException if the {@code remove} operation
* is not supported by this map
* (optional)
* @throws ClassCastException if the key or value is of an inappropriate
* type for this map
* (optional)
* @throws NullPointerException if the specified key or value is null,
* and this map does not permit null keys or values
* (optional)
* @since 1.8
*/
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;
}
/**
* 替换指定key对应的entry,当且仅当指定的key映射到指定的value。
*
*
对于这个map,默认的实现与下面相同:
*
*
{@code
* if (map.containsKey(key) && Objects.equals(map.get(key), value)) {
* map.put(key, newValue);
* return true;
* } else
* return false;
* }
*
* 默认的实现,如果oldValue为null,对于不支持null值的map,不会抛出NullPointerException,
* 除非newValue也是null
*
* 默认的实现不保证方法的同步性或者原子性。
* 任何提供了原子性的实现,必须覆盖这个方法,并且报告它的并发属性。
*
* @param key key with which the specified value is associated
* @param oldValue value expected to be associated with the specified key
* @param newValue value to be associated with the specified key
* @return {@code true} if the value was replaced
* @throws UnsupportedOperationException if the {@code put} operation
* is not supported by this map
* (optional)
* @throws ClassCastException if the class of a specified key or value
* prevents it from being stored in this map
* @throws NullPointerException if a specified key or newValue is null,
* and this map does not permit null keys or values
* @throws NullPointerException if oldValue is null and this map does not
* permit null values
* (optional)
* @throws IllegalArgumentException if some property of a specified key
* or value prevents it from being stored in this map
* @since 1.8
*/
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;
}
/**
* 替换指定的key对应的entry,当且仅当指定的key映射到一些value(就是map.containsKey(key)为true)
*
*
对于这个map,默认的实现与下面相同:
*
*
{@code
* if (map.containsKey(key)) {
* return map.put(key, value);
* } else
* return null;
* }
*
* 默认的实现不保证方法的同步性或者原子性。
* 任何提供了原子性的实现,必须覆盖这个方法,并且报告它的并发属性。
*
* @param key key with which the specified value is associated
* @param value value to be associated with the specified key
* @return the previous value associated with the specified key, or
* {@code null} if there was no mapping for the key.
* (A {@code null} return can also indicate that the map
* previously associated {@code null} with the key,
* if the implementation supports null values.)
* @throws UnsupportedOperationException if the {@code put} operation
* is not supported by this map
* (optional)
* @throws ClassCastException if the class of the specified key or value
* prevents it from being stored in this map
* (optional)
* @throws NullPointerException if the specified key or value is null,
* and this map does not permit null keys or values
* @throws IllegalArgumentException if some property of the specified key
* or value prevents it from being stored in this map
* @since 1.8
*/
default V replace(K key, V value) {
V curValue;
if (((curValue = get(key)) != null) || containsKey(key)) {
curValue = put(key, value);
}
return curValue;
}
/**
* 如果指定的key没有与value关联(或者映射到null),使用给定的映射function计算
* key对应的value,并将它放入map中,除非计算出的value为null
*
* 如果function返回null,不放入map。
* 如果function抛出一个未检查异常,异常被重新抛出,不放入map。
* 最通常的用法是value是一个新对象,使用key作为初始参数:
*
*
{@code
* map.computeIfAbsent(key, k -> new Value(f(k)));
* }
*
* 或者实现一个多重value的map,{@code Map>},
* 支持每个key有多个value
*
* {@code
* map.computeIfAbsent(key, k -> new HashSet()).add(v);
* }
*
*
* 默认的实现对这个map,与以下几步相同,然后返回当前的value或者null(如果现在空缺)
*
* {@code
* if (map.get(key) == null) {
* V newValue = mappingFunction.apply(key);
* if (newValue != null)
* map.put(key, newValue);
* }
* }
*
* 默认的实现不保证方法的同步性或者原子性。
* 任何提供了原子性的实现,必须覆盖这个方法,并且报告它的并发属性。
* 尤其是所有ConcurrentMap的实现必须记录函数是否仅在值不存在时才原子地应用一次。
*
* @param key key with which the specified value is to be associated
* @param mappingFunction the function to compute a value
* @return the current (existing or computed) value associated with
* the specified key, or null if the computed value is null
* @throws NullPointerException if the specified key is null and
* this map does not support null keys, or the mappingFunction
* is null
* @throws UnsupportedOperationException if the {@code put} operation
* is not supported by this map
* (optional)
* @throws ClassCastException if the class of the specified key or value
* prevents it from being stored in this map
* (optional)
* @since 1.8
*/
default V computeIfAbsent(K key,
Function super K, ? extends V> mappingFunction) {
Objects.requireNonNull(mappingFunction);
V v;
if ((v = get(key)) == null) { // 如果key对应的value为null或者不存在
V newValue;
if ((newValue = mappingFunction.apply(key)) != null) { // 如果计算出的新value不为null
put(key, newValue);
return newValue;
}
}
return v;
}
/**
* 如果指定的key对应的value存在,而且非null,尝试使用给定的key和当前映射的value计算出一个新的映射。
*
*
如果function返回null,映射被删除。
* 如果function抛出未检查异常,异常被重新抛出,当前映射不被修改。
*
*
默认的实现对这个map,与以下几步相同,然后返回当前的value或者null(如果现在空缺)
*
*
{@code
* 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的实现必须记录函数是否仅在值不存在时才原子地应用一次。
*
* @param key key with which the specified value is to be associated
* @param remappingFunction the function to compute a value
* @return the new value associated with the specified key, or null if none
* @throws NullPointerException if the specified key is null and
* this map does not support null keys, or the
* remappingFunction is null
* @throws UnsupportedOperationException if the {@code put} operation
* is not supported by this map
* (optional)
* @throws ClassCastException if the class of the specified key or value
* prevents it from being stored in this map
* (optional)
* @since 1.8
*/
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;
}
}
/**
* 尝试使用指定的key和它当前的value(或者null,如果没有当前映射)。
* 例如,创建或者添加一个String的消息,对于map:
*
*
{@code
* map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg))}
* (方法 {@link #merge merge()} 通常用于这种目的)
*
* 如果function返回null,移除这个映射(如果一开始就没有,就还是没有)。
* 如果function抛出未检查异常,异常被重新抛出,当前映射不被修改。
*
*
默认的实现对这个map,与以下几步相同,然后返回当前的value或者null(如果现在空缺)
*
*
{@code
* 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的实现必须记录函数是否仅在值不存在时才原子地应用一次。
*
* @param key key with which the specified value is to be associated
* @param remappingFunction the function to compute a value
* @return the new value associated with the specified key, or null if none
* @throws NullPointerException if the specified key is null and
* this map does not support null keys, or the
* remappingFunction is null
* @throws UnsupportedOperationException if the {@code put} operation
* is not supported by this map
* (optional)
* @throws ClassCastException if the class of the specified key or value
* prevents it from being stored in this map
* (optional)
* @since 1.8
*/
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) {
// 删除映射
if (oldValue != null || containsKey(key)) {
// 有删除的东西
remove(key);
return null;
} else {
// 没事可干
return null;
}
} else {
// 增加映射或者替代老映射
put(key, newValue);
return newValue;
}
}
/**
* 如果指定的key没有与value关联或者与null关联,使用给定的非null值关联。
* 否则,使用给定的重映射function的结果替代value,或者如果结果为null,删除它。
* 这个方法可以在当合并key映射的value时用。
* 例如,创建或者增加一个msg:
*
*
{@code
* map.merge(key, msg, String::concat)
* }
*
* 如果这个function返回null,删除这个映射。
* 如果function抛出未检查异常,异常被重新抛出,当前映射不被修改。
*
*
默认的实现对这个map,与以下几步相同,然后返回当前的value或者null(如果现在空缺)
*
*
{@code
* 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的实现必须记录函数是否仅在值不存在时才原子地应用一次。
*
* @param key key with which the resulting value is to be associated
* @param value the non-null value to be merged with the existing value
* associated with the key or, if no existing value or a null value
* is associated with the key, to be associated with the key
* @param remappingFunction the function to recompute a value if present
* @return the new value associated with the specified key, or null if no
* value is associated with the key
* @throws UnsupportedOperationException if the {@code put} operation
* is not supported by this map
* (optional)
* @throws ClassCastException if the class of the specified key or value
* prevents it from being stored in this map
* (optional)
* @throws NullPointerException if the specified key is null and this map
* does not support null keys or the value or remappingFunction is
* null
* @since 1.8
*/
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;
}