原理简介:
HashMap是利用哈希表原理来存储元素的一种集合。在JDK1.7中,HashMap底层是 数组+链表 的, 在JDK1.8以后,HashMap底层改为 数组+链表+红黑树 构成, 效率也变的更高效。

HashMap源码主要从几个方面来看.

一 定义
  public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable   

  继承AbstractMap 实现Map接口, Cloneable接口 ,能复制和序列化.


二 成员变量 (原理中必须要用到的几个重要参数)
  private static final long serialVersionUID = 362498820763181265L;         // UID 序列化用的.不解释
  static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;                       // aka 16, 初始化的数组容量, 默认是16. 必须是2的倍数.
  static final int MAXIMUM_CAPACITY = 1 << 30;                              // 集合最大容量,1 << 30 为2的30次幂. 10亿多.
  static final float DEFAULT_LOAD_FACTOR = 0.75f;                           // 扩展因子, 0.75, 当数组中元素数量超过总容量的0.75倍(如默认容量16的0.75倍 12时,就会自动扩容)
  static final int TREEIFY_THRESHOLD = 8;                          // 树化阈值(JDK1.8新增), 8 ,也就是当链表中元素个数大于等于8时, 链表会转化为红黑树.对照下面的树退化阈值记忆.
  static final int UNTREEIFY_THRESHOLD = 6;                                 // 树退化阈值(JDK1.8新增), 6, 当红黑树中元素个数少于等于6时, 红黑树会转化为链表. 呼应前面的树化阈值.
  static final int MIN_TREEIFY_CAPACITY = 64;                   // 当map中键值对总数量大于64时, 才会去判断上面的树化阈值.小于64时, 桶内元素太多只会扩容,不会化成树.
                                              //为了避免扩容和树形化选择冲突,这个值不能低于4*TREEIFY_THRESHOLD ,即32.

  

三  桶结构源码(从源码中可以看出,hash方式为key和value分别哈希,结果再异或)
    static class Node<K,V> implements Map.Entry<K,V> {
        final int hash;
        final K key;
        V value;
        Node<K,V> next;

        Node(int hash, K key, V value, Node<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }

        public final K getKey()        { return key; }
        public final V getValue()      { return value; }
        public final String toString() { return key + "=" + value; }

        public final int hashCode() {
            return Objects.hashCode(key) ^ Objects.hashCode(value);
        }

        public final V setValue(V newValue) {
            V oldValue = value;
            value = newValue;
            return oldValue;
        }

        public final boolean equals(Object o) {
            if (o == this)
                return true;
            if (o instanceof Map.Entry) {
                Map.Entry<?,?> e = (Map.Entry<?,?>)o;
                if (Objects.equals(key, e.getKey()) &&
                    Objects.equals(value, e.getValue()))
                    return true;
            }
            return false;
        }
    }

 

 

  

 

  



  

  





posted on 2021-01-03 20:27  榕树下的笨青蛙  阅读(158)  评论(0)    收藏  举报