上一篇文章分析了红黑树(主要是红黑树的添加操作,来维护红黑树的结构),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的分析。