jdk源码——集合(二)

      上一篇文章分析了红黑树(主要是红黑树的添加操作,来维护红黑树的结构),jdk源码——集合(红黑树),这一文章,来分析HashMap的源码,所以这篇文章的顺序是Map,AbstractMap,HashMap。这篇文章应该是为分析HashMap源码的准备篇吧。

    

public interface Map<K,V> {
    /*
    接口中的方法或者成员变量,都被public Static 修饰
    default关键字可以让接口中的方法可以有默认的函数体,当一个类实现这个接口时,
    可以不用去实现这个方法,当然,这个类若实现这个方法,就等于子类覆盖了这个方法,最终运行结果符合Java多态特性
     */
    
    /*
    获得map的长度
     */
    int size();
    
   /*
   判断map是否为空
    */
    boolean isEmpty();
    
    /*
    判断是否包含key
     */
    boolean containsKey(Object key);
    
    /*
   判断是否包含value
    */
    boolean containsValue(Object value);
    
    /*
   返回指定key的value
    */
    V get(Object key);

    /*
   添加一个元素
    */
    V put(K key, V value);

    /*
   删除key指定的元素
    */
    V remove(Object key);

    /*
   添加一个集合
    */
    void putAll(Map<? extends K, ? extends V> m);
    
    /*
   清空
    */
    void clear();
    
    /*
   将所有的key添加到一个set集合中,并返回一个Set集合
    */
    Set<K> keySet();
    
    /*
   将所有的value值添加到一个集合中,并返回一个Collection
    */
    Collection<V> values();
    
    /*
   返回此映射中包含的映射关系的 Set 视图,例如:[1=haha, 2=hehe, 3=xixi],就是一个Set集合,元素类型是一个Map.Entry<K, V>
    */
    Set<Map.Entry<K, V>> entrySet();
    
    /*
    内部接口,该接口的作用是,取出map的一个映射关系,将map的key值和value值存储在一个Entry的对象中
     */
    interface Entry<K,V> {

        K getKey();


        V getValue();


        V setValue(V value);


        boolean equals(Object o);


        int hashCode();


        public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> comparingByKey() {
            return (Comparator<Map.Entry<K, V>> & Serializable)
                (c1, c2) -> c1.getKey().compareTo(c2.getKey());
        }


        public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K,V>> comparingByValue() {
            return (Comparator<Map.Entry<K, V>> & Serializable)
                (c1, c2) -> c1.getValue().compareTo(c2.getValue());
        }


        public static <K, V> Comparator<Map.Entry<K, V>> comparingByKey(Comparator<? super K> cmp) {
            Objects.requireNonNull(cmp);
            return (Comparator<Map.Entry<K, V>> & Serializable)
                (c1, c2) -> cmp.compare(c1.getKey(), c2.getKey());
        }

        public static <K, V> Comparator<Map.Entry<K, V>> comparingByValue(Comparator<? super V> cmp) {
            Objects.requireNonNull(cmp);
            return (Comparator<Map.Entry<K, V>> & Serializable)
                (c1, c2) -> cmp.compare(c1.getValue(), c2.getValue());
        }
    }


    /*
    判断两个集合是否相等,值得是内容
     */
    boolean equals(Object o);

     /*
     获得hash值
      */
    int hashCode();

/*
  default关键字是jdk1.8的新特性,也就是说以下方法都是jdk1.8以后新添加的方法
*/
//得到key对应的value值,若value为null,则返回参数defaultValue
    default V getOrDefault(Object key, V defaultValue) {
        V v;
        return (((v = get(key)) != null) || containsKey(key))
            ? v
            : defaultValue;
    }


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


    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);
            }
        }
    }


    /*
    //若key对应的value是null,则用传入的value代替他
     */
    default V putIfAbsent(K key, V value) {
        V v = get(key);
        if (v == null) {
            v = put(key, value);
        }

        return v;
    }


    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;
    }

    //替换value
    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
    default V replace(K key, V value) {
        V curValue;
        if (((curValue = get(key)) != null) || containsKey(key)) {
            curValue = put(key, value);
        }
        return curValue;
    }


    default V computeIfAbsent(K key,
            Function<? super K, ? extends V> mappingFunction) {
        Objects.requireNonNull(mappingFunction);
        V v;
        if ((v = get(key)) == null) {
            V newValue;
            if ((newValue = mappingFunction.apply(key)) != null) {
                put(key, newValue);
                return newValue;
            }
        }

        return v;
    }


    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;
        }
    }


    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) {
            // delete mapping
            if (oldValue != null || containsKey(key)) {
                // something to remove
                remove(key);
                return null;
            } else {
                // nothing to do. Leave things as they were.
                return null;
            }
        } else {
            // add or replace old mapping
            put(key, newValue);
            return newValue;
        }
    }


    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;
    }
}


     中间有几个方法没有看,所以没有写注释,如果你想看的看,可以仔细研究一下了,哈哈!


    下面是AbstractMap的元源码。

/*
该类为一个抽象类,所以这个类中有抽象的方法,经查看,只有一个抽象方法,是entrySet()方法,返回一个Set<Entry<K,V>>,
这个方法就是将Map的key-value映射放在set集合中,而且,这个类的很多方法都调用了此类。
 */
public abstract class AbstractMap<K,V> implements Map<K,V> {

    /*
    构造方法的修饰符是protected,该包或者该类的子类可以访问
     */
    protected AbstractMap() {
    }

    /*
    获得长度,就是获得一个Set集合,获得这个集合的长度
     */
    public int size() {
        return entrySet().size();
    }

    /*
    判断这个集合是否为空,判断的就是Set集合的长度是否为o
     */
    public boolean isEmpty() {
        return size() == 0;
    }

    /*
    根据value,判断是否含有指定元素,底层是根据Set集合,遍历Set集合(遍历集合,使用的是iterator,iterator的好处在与不需要知道类
    型,只要是Collection就可以)
     */
    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;
    }

    /*
    根据指定的key,判断是否含有该元素,和containsValue()方法类似
     */
    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;
    }

    /*
    底层都是一个set集合,和containsValue和containsKey方法,都一样
     */
    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;
    }


    /*
    抽象类没有提供添加操作,调用此方法添加会报错
     */
    public V put(K key, V value) {
        throw new UnsupportedOperationException();
    }


    /*
    根据指定key删除该映射,并返回该映射的value值,需要先获得该元素,
     */
    public V remove(Object key) {
        Iterator<Entry<K,V>> i = entrySet().iterator();
        Entry<K,V> correctEntry = null;//查找到的元素赋给correctEntry
        if (key==null) {
            while (correctEntry==null && i.hasNext()) {
                Entry<K,V> e = i.next();
                if (e.getKey()==null)
                    //获得key为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();//获得value,并返回
            i.remove();//删除
        }
        return oldValue;
    }



    /*
     将其他映射添加到该映射中,for循环
     */
    public void putAll(Map<? extends K, ? extends V> m) {
        for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
            put(e.getKey(), e.getValue());
    }


    /*
    清除所有映射关系
     */
    public void clear() {
        entrySet().clear();
    }



    transient volatile Set<K>        keySet;//不被序列化,将所有的key放到Set中
    transient volatile Collection<V> values;//不被序列化,将所有的value值放到Collection中


    /*
    获得所有的key,赋值给keyset,获得ketset,并没有使用我们想象中的for遍历,取出key,让后将key放到set集合中,如果数据量太大时,
     就会影响效率,
     */
    public Set<K> keySet() {
        if (keySet == null) {
            /*该方法创建了一个内部类对象,等于创建一个AbstractSet的子类,实现了iterator(),因为这个方法要返回一个Iterator,
             所以创建了一个Iterator类,并实现Iterator的方法。
            其实就是创建了一个AbstractSet子类的对象
            */
            keySet = new AbstractSet<K>() {
                public Iterator<K> iterator() {
                    return new Iterator<K>() {
                        //创建了一个匿名内部类,创建了一个自定义的Iterator的子类
                        private Iterator<Entry<K,V>> i = entrySet().iterator();//引用Entry的Set集合Iterator迭代器

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

                        public K next() {
                            return i.next().getKey();
                        }//这个方法获取key值

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

                //以下方法是Set集合
                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);
                }
            };
        }
        return keySet;
    }

   /*
   和keySet()一样,只不过创建的是AbstractCollection的子类对象,实现iterator(),
    */
    public Collection<V> values() {
        if (values == null) {
            values = 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);
                }
            };
        }
        return values;
    }

    /*
获得所有映射关系,该方法是一个抽象方法,所以子类必须实现它
     */
    public abstract Set<Entry<K,V>> entrySet();



/*
判断两个集合是否相等
 */
    public boolean equals(Object o) {
        if (o == this)//先判断是不是本对象,如果是本对象,直接放回true
            return true;

        if (!(o instanceof Map))//判断对象类型是不是Map
            return false;
        Map<?,?> m = (Map<?,?>) o;//是Map类型,强制转换成相同类型
        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) {
                    //value为null时,判断key值
                    if (!(m.get(key)==null && m.containsKey(key)))
                        return false;
                } else {
                    //value不为null,判断value值
                    if (!value.equals(m.get(key)))
                        return false;
                }
            }
        } catch (ClassCastException unused) {
            return false;
        } catch (NullPointerException unused) {
            return false;
        }

        return true;
    }

    /*
    hashcode值,map的hashcode的值是由每个元素的hashcode的值相加而得到的
     */
    public int hashCode() {
        int h = 0;
        Iterator<Entry<K,V>> i = entrySet().iterator();
        while (i.hasNext())
            h += i.next().hashCode();
        return h;
    }


    /*
    toString(),底层使用的是StringBuilder,可变字符串,
     */
    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(' ');
        }
    }


    /*
    对象的克隆,返回的是一个新的对象
     */
    protected Object clone() throws CloneNotSupportedException {
        AbstractMap<?,?> result = (AbstractMap<?,?>)super.clone();
        result.keySet = null;
        result.values = null;
        return result;
    }


   /*
   判断两个对象是否相等
    */
    private static boolean eq(Object o1, Object o2) {
        return o1 == null ? o2 == null : o1.equals(o2);
    }



    /*
   该类有两个内部类,都是实现Entry接口,使用的SimpleEntry的话,key值不可变,value可变,使用的是SimpleImmutableEntry的话,key和value
   都是不可变的,其余的都一样,只有这一点不同
    */
    /*
    内部类
     */

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

        private final K key;//是final,就是说key是不可变的
        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;
        }


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


        public int hashCode() {
            return (key   == null ? 0 :   key.hashCode()) ^
                   (value == null ? 0 : value.hashCode());
        }


        public String toString() {
            return key + "=" + value;
        }

    }


    /*
    内部类,实现Entry
     */
    public static class SimpleImmutableEntry<K,V>
        implements Entry<K,V>, java.io.Serializable
    {
        private static final long serialVersionUID = 7138329143949025153L;

        private final K key;//key不可变
        private final V value;//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();
        }


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


        public int hashCode() {
            return (key   == null ? 0 :   key.hashCode()) ^
                   (value == null ? 0 : value.hashCode());
        }


        public String toString() {
            return key + "=" + value;
        }

    }

}
最主要的就是,keyset()和values()都是同创建匿名内部类而实现的。

下一篇正式开始HashMap的分析。


猜你喜欢

转载自blog.csdn.net/qq_36838854/article/details/80337024