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是线程不安全的。

posted @ 2018-09-17 13:59  小情绪Ango  阅读(199)  评论(0编辑  收藏  举报