1. 程式人生 > >Map容器家族(AbstractMap原始碼詳解)

Map容器家族(AbstractMap原始碼詳解)

一、在Map集合體系中的位置及概述

        AbstractMap抽象類提供Map介面的骨幹實現,以最大限度地減少實現此介面所需的工作量。

二、成員變數

    // 儲存key
    transient Set<K>        keySet;
    // 儲存value
    transient Collection<V> values;

三、方法詳解

1.新增方法

    /**
     * 功能:向map中新增元素
     * 注:這個方法並沒有實現
     */
    public V put(K key, V value) {
        throw new UnsupportedOperationException();
    }

2.刪除方法

    /**
     * 功能:刪除所有鍵值對
     * 實現:
     * 1.呼叫Set集合的clear方法進行刪除
     */
    public void clear() {
        entrySet().clear();
    }

3.修改方法(Modification Operations)

    /**
     * 功能:根據鍵移除該鍵值對
     * 實現:
     * 1.獲取儲存Entry的Set迭代器,並建立臨時儲存要刪除的Entry的變數correctEntry
     * 2.如果待刪除的key為null:
     *      2.1 如果correctEntry中沒有元素並且有下一個元素進行迭代,比較key值是否為null,如果為null將該Entry賦給correctEntry,迭代結束
     * 3.如果待刪除的key不為null,操作同步驟2
     * 4.如果correctEntry為null,函式直接返回null
     * 5.如果correctEntry不為Null,將待刪除的Entry值返回,並呼叫Set的remove方法刪除該Entry
     */
    public V remove(Object key) {
        Iterator<Entry<K,V>> i = entrySet().iterator();
        Entry<K,V> correctEntry = null;
        if (key==null) {
            while (correctEntry==null && i.hasNext()) {
                Entry<K,V> e = i.next();
                if (e.getKey()==null)
                    correctEntry = e;
            }
        } else {
            while (correctEntry==null && i.hasNext()) {
                Entry<K,V> e = i.next();
                if (key.equals(e.getKey()))
                    correctEntry = e;
            }
        }

        V oldValue = null;
        if (correctEntry !=null) {
            oldValue = correctEntry.getValue();
            i.remove();
        }
        return oldValue;
    }

4.查詢方法(Query Operations)

    /**
     * 功能:返回map元素個數
     * 實現:
     * 1.entrySet方法返回的是Set集合,呼叫Set集合的size方法獲取鍵值對的個數
     */
    public int size() {
        return entrySet().size();
    }

    /**
     * 功能:該map集合是否為空
     * 實現:
     * 1.通過判斷集合元素個數size是否為0即可判斷是否為空
     */
    public boolean isEmpty() {
        return size() == 0;
    }

    /**
     * 功能:判斷集合是否包含指定值
     * 功能:
     * 1.獲取鍵值對的Set集合
     * 2.如果指定元素為null,使用Set迭代器遍歷集合比較
     * 3.如果指定元素不為null,使用Set迭代器遍歷集合比較
     * 4.如果沒有找到返回false
     */
    public boolean containsValue(Object value) {
        Iterator<Entry<K,V>> i = entrySet().iterator();
        if (value==null) {
            while (i.hasNext()) {
                Entry<K,V> e = i.next();
                if (e.getValue()==null)
                    return true;
            }
        } else {
            while (i.hasNext()) {
                Entry<K,V> e = i.next();
                if (value.equals(e.getValue()))
                    return true;
            }
        }
        return false;
    }

    /**
     * 功能:判斷集合是否包含指定鍵
     * 實現:同上一個方法
     */
    public boolean containsKey(Object key) {
        Iterator<Map.Entry<K,V>> i = entrySet().iterator();
        if (key==null) {
            while (i.hasNext()) {
                Entry<K,V> e = i.next();
                if (e.getKey()==null)
                    return true;
            }
        } else {
            while (i.hasNext()) {
                Entry<K,V> e = i.next();
                if (key.equals(e.getKey()))
                    return true;
            }
        }
        return false;
    }

    /**
     * 功能:根據鍵獲取值
     * 實現:
     * 1.獲取鍵值對的Set集合
     * 2.如果指定的key為null,遍歷集合,如果找到為null的key,則返回key
     * 3.如果指定的key不為空,遍歷集合,如果找到key,則返回key
     * 4.如果沒找到,則返回null
     */
    public V get(Object key) {
        Iterator<Entry<K,V>> i = entrySet().iterator();
        if (key==null) {
            while (i.hasNext()) {
                Entry<K,V> e = i.next();
                if (e.getKey()==null)
                    return e.getValue();
            }
        } else {
            while (i.hasNext()) {
                Entry<K,V> e = i.next();
                if (key.equals(e.getKey()))
                    return e.getValue();
            }
        }
        return null;
    }

5.批量操作(Bulk Operations)

    /**
     * 功能:新增一個map集合的元素到該集合中
     * 實現:
     * 1.使用增強for遍歷該map的集合,使用put方法逐個新增
     */
    public void putAll(Map<? extends K, ? extends V> m) {
        for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
            put(e.getKey(), e.getValue());
    }

6.檢視

    /**
     * 功能:返回鍵的Set集合
     * 實現:
     * 1.將keySet的地址應用賦給ks
     * 2.如果ks沒有為null(沒有初始化),建立AbstractSet的子類並對其中的方法進行實現,獲取到entrySet()
     *   的迭代器,就等同於獲取到他的所有元素;
     * 3.返回ks
     * 
     * 注:
     *  1.這個方法的主體功能在呼叫的第一次會對keySet進行初始化,以後再次呼叫將不會執行主方法體,
     *    直接返回keySet。
     *  2.獲取到一個結合迭代器在一定程度上就等同於獲取到集合所有元素
     */
    public Set<K> keySet() {
        Set<K> ks = keySet;
        if (ks == null) {
            ks = new AbstractSet<K>() {
                public Iterator<K> iterator() {
                    return new Iterator<K>() {
                        private Iterator<Entry<K,V>> i = entrySet().iterator();

                        public boolean hasNext() {
                            return i.hasNext();
                        }

                        public K next() {
                            return i.next().getKey();
                        }

                        public void remove() {
                            i.remove();
                        }
                    };
                }

                public int size() {
                    return AbstractMap.this.size();
                }

                public boolean isEmpty() {
                    return AbstractMap.this.isEmpty();
                }

                public void clear() {
                    AbstractMap.this.clear();
                }

                public boolean contains(Object k) {
                    return AbstractMap.this.containsKey(k);
                }
            };
            keySet = ks;
        }
        return ks;
    }

    /**
     * 功能:獲取所有的值,並以Collection集合的形式返回
     * 實現:原理同keySet方法
     */
    public Collection<V> values() {
        Collection<V> vals = values;
        if (vals == null) {
            vals = new AbstractCollection<V>() {
                public Iterator<V> iterator() {
                    return new Iterator<V>() {
                        private Iterator<Entry<K,V>> i = entrySet().iterator();

                        public boolean hasNext() {
                            return i.hasNext();
                        }

                        public V next() {
                            return i.next().getValue();
                        }

                        public void remove() {
                            i.remove();
                        }
                    };
                }

                public int size() {
                    return AbstractMap.this.size();
                }

                public boolean isEmpty() {
                    return AbstractMap.this.isEmpty();
                }

                public void clear() {
                    AbstractMap.this.clear();
                }

                public boolean contains(Object v) {
                    return AbstractMap.this.containsValue(v);
                }
            };
            values = vals;
        }
        return vals;
    }

7.核心方法

    public abstract Set<Entry<K,V>> entrySet();

8.比較和雜湊(Comparison and hashing)

    /**
     * 功能:比較是否相等
     * 實現:
     * 1.如果o是本集合,則返回true
     * 2.如果o資料型別不是map,則返回false
     * 3.使用泛型萬用字元,將o轉換成m
     * 4.獲取本集合的Entry迭代器
     * 5.進行迭代分兩種情況比較
     */
    public boolean equals(Object o) {
        if (o == this)
            return true;

        if (!(o instanceof Map))
            return false;
        Map<?,?> m = (Map<?,?>) o;
        if (m.size() != size())
            return false;

        try {
            Iterator<Entry<K,V>> i = entrySet().iterator();
            while (i.hasNext()) {
                Entry<K,V> e = i.next();
                K key = e.getKey();
                V value = e.getValue();
                if (value == null) {
                    if (!(m.get(key)==null && m.containsKey(key)))
                        return false;
                } else {
                    if (!value.equals(m.get(key)))
                        return false;
                }
            }
        } catch (ClassCastException unused) {
            return false;
        } catch (NullPointerException unused) {
            return false;
        }

        return true;
    }

    /**
     * 功能:返回次map集合的雜湊值
     * 實現:
     * 1.遍歷迭代每一個Entry,並將每個Entry的雜湊值相加求和並返回
     */
    public int hashCode() {
        int h = 0;
        Iterator<Entry<K,V>> i = entrySet().iterator();
        while (i.hasNext())
            h += i.next().hashCode();
        return h;
    }

9.其他方法

    /**
     * 功能:將map集合以字串表示
     * 實現:一看就能懂
     */
    public String toString() {
        Iterator<Entry<K,V>> i = entrySet().iterator();
        if (! i.hasNext())
            return "{}";

        StringBuilder sb = new StringBuilder();
        sb.append('{');
        for (;;) {
            Entry<K,V> e = i.next();
            K key = e.getKey();
            V value = e.getValue();
            sb.append(key   == this ? "(this Map)" : key);
            sb.append('=');
            sb.append(value == this ? "(this Map)" : value);
            if (! i.hasNext())
                return sb.append('}').toString();
            sb.append(',').append(' ');
        }
    }

    /**
     * 功能:淺度克隆該map集合
     * 注:不克隆鍵和值的集合
     */
    protected Object clone() throws CloneNotSupportedException {
        AbstractMap<?,?> result = (AbstractMap<?,?>)super.clone();
        result.keySet = null;
        result.values = null;
        return result;
    }

四、兩個實現了Entry介面的靜態方法

       這兩個方法分別為SimpleEntry靜態類和SimpleImmutableEntry靜態類。這兩個類的程式碼有99%都是相同的。只有setValue是不同的,SimpleEntry支援setValue功能而SimpleImmutableEntry不支援setValue方法,這也是這兩個類的主要區別,即SimpleEntry是執行緒不安全的Entry的實現而SimpleImmutableEntry是執行緒安全的Entry的實現.

    /**
     * Map介面的Entry實現類
     */
    public static class SimpleEntry<K,V>
        implements Entry<K,V>, java.io.Serializable
    {
        private static final long serialVersionUID = -8499721149061103585L;

        // key值
        private final K key;
        // value值
        private V value;

        /**
         * 功能:構造方法
         */
        public SimpleEntry(K key, V value) {
            this.key   = key;
            this.value = value;
        }

        /**
         * 功能:構造方法
         */
        public SimpleEntry(Entry<? extends K, ? extends V> entry) {
            this.key   = entry.getKey();
            this.value = entry.getValue();
        }

        /**
         * 功能:獲取鍵
         */
        public K getKey() {
            return key;
        }

        /**
         * 功能:獲取值
         */
        public V getValue() {
            return value;
        }

        /**
         * 功能:設定值並返回以前的值
         */
        public V setValue(V value) {
            V oldValue = this.value;
            this.value = value;
            return oldValue;
        }

        /**
         * 功能:比較兩個Entry是否相等
         */
        public boolean equals(Object o) {
            if (!(o instanceof Map.Entry))
                return false;
            Map.Entry<?,?> e = (Map.Entry<?,?>)o;
            return eq(key, e.getKey()) && eq(value, e.getValue());
        }

        /**
         * 功能:返回此SimpleEntry的雜湊值
         * 注:^ 為異或運算子
         */
        public int hashCode() {
            return (key   == null ? 0 :   key.hashCode()) ^
                   (value == null ? 0 : value.hashCode());
        }

        /**
         * 功能:返回此SimpleEntry的字串表示
         */
        public String toString() {
            return key + "=" + value;
        }

    }

    public static class SimpleImmutableEntry<K,V>
        implements Entry<K,V>, java.io.Serializable
    {
        private static final long serialVersionUID = 7138329143949025153L;

        private final K key;
        private final V value;

        /**
         * 功能:構造方法
         */
        public SimpleImmutableEntry(K key, V value) {
            this.key   = key;
            this.value = value;
        }

        /**
         * 功能:構造方法
         */
        public SimpleImmutableEntry(Entry<? extends K, ? extends V> entry) {
            this.key   = entry.getKey();
            this.value = entry.getValue();
        }

        /**
         * 功能:獲取鍵
         */
        public K getKey() {
            return key;
        }

        /**
         * 功能:獲取值
         */
        public V getValue() {
            return value;
        }

        /**
         * 功能:設定值
         * 注:此方法,為了保證執行緒安全,此類不實現
         */
        public V setValue(V value) {
            throw new UnsupportedOperationException();
        }

        /**
         * 功能:比較兩個Entry是否相等
         */
        public boolean equals(Object o) {
            if (!(o instanceof Map.Entry))
                return false;
            Map.Entry<?,?> e = (Map.Entry<?,?>)o;
            return eq(key, e.getKey()) && eq(value, e.getValue());
        }

        /**
         * 功能:返回此SimpleEntry的雜湊值
         * 注:^ 為異或運算子
         */
        public int hashCode() {
            return (key   == null ? 0 :   key.hashCode()) ^
                   (value == null ? 0 : value.hashCode());
        }

        /**
         * 功能:返回此SimpleEntry的字串表示
         */
        public String toString() {
            return key + "=" + value;
        }

    }

五、總結

        AbstractMap抽象類提供Map介面的骨幹實現,以最大限度地減少實現此介面所需的工作量。

        此類中有兩個Map介面中Entry介面的靜態實現,SimpleEntry類和SimpleImmutableEntry。SimpleEntry是執行緒安全的,SimpleImmutableEntry是執行緒不安全的。