java容器 接口Map源码分析

目录

简介

查询 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

java容器 接口Map源码分析_第1张图片

查询 size,isEmpty,containsKey,containsValue

    // 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的增删改查 get,put,remove

    /**
     * 得到指定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);

批量操作 putAll,clear

    // 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 m);

    /**
     * 删除map中所有的映射(可选操作)。
     * 调用返回后,map为空。
     *
     * @throws UnsupportedOperationException if the clear operation
     *         is not supported by this map
     */
    void clear();

Entry接口

简介

    /**
     * 一个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

对key和value的操作 getKey,setValue,getValue

        /**
         * 返回这个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);

equals,hashcode

        /**
         * 将指定对象与这个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 comparingByKey两个,comparingByValue

        /**
         * 返回一个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 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 cmp) { Objects.requireNonNull(cmp); return (Comparator> & Serializable) (c1, c2) -> cmp.compare(c1.getValue(), c2.getValue()); }

视图 keySet,values,entrySet

    // 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();

equals,hashCode

    /**
     * 将指定对象与这个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();

批量操作 forEach,replaceAll

    /**
     * 对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 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 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); } } }

单个操作 getOrDefault,putIfAbsent,remove,两个replace

    /**
     * 

返回指定的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; }

三个computeXXX,merge

    /**
     * 如果指定的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 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 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 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 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; }

 

 

 

 

 

 

 

你可能感兴趣的:(java容器,源码分析)