HashMap源碼學習(基於jdk1.8)

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
HashMap數據結構示意圖

//默認初始化容量,必須是2的冪次

static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;


//最大容量,如果指定其它較大值時,則必須是2的冪次,且小於等於1<<30

static final int MAXIMUM_CAPACITY = 1 << 30;


//默認負載因子

static final float DEFAULT_LOAD_FACTOR = 0.75f;


//樹化結構最小鏈節點數,即單個表節點上的鏈節點超過8個時纔會轉換爲紅黑樹進行存儲

static final int TREEIFY_THRESHOLD = 8;


//樹結構轉爲鏈結構時的樹節點數,即與上面的參數相對應

static final int UNTREEIFY_THRESHOLD = 6;


//樹化結構的最小表節點數,即小於這個數時,不會進行鏈表轉紅黑樹,而是給表擴容

static final int MIN_TREEIFY_CAPACITY = 64;

內部類Node<K,V>不再贅述,比較簡單

/*
* 計算node在map中存取時使用的hash值
*/
    static final int hash(Object key) {
        int h;
        //當key不爲null時,將key的hashcode的前16位和後16位做異計算返回
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }
/*
* 判斷若x實現了Comparable<C>接口,則返回x的類型,否則返回空
*/

    static Class<?> comparableClassFor(Object x) {
        if (x instanceof Comparable) {
            Class<?> c; Type[] ts, as; Type t; ParameterizedType p;
            if ((c = x.getClass()) == String.class) // bypass checks
                return c;
            if ((ts = c.getGenericInterfaces()) != null) {
                for (int i = 0; i < ts.length; ++i) {
                    if (((t = ts[i]) instanceof ParameterizedType) &&
                        ((p = (ParameterizedType)t).getRawType() ==
                         Comparable.class) &&
                        (as = p.getActualTypeArguments()) != null &&
                        as.length == 1 && as[0] == c) // type arg is c
                        return c;
                }
            }
        }
        return null;
    }
/*
* 若x爲空或者不是kc類型則返回0,否則返回x和k的對比值
*/

    static int compareComparables(Class<?> kc, Object k, Object x) {
        return (x == null || x.getClass() != kc ? 0 :
                ((Comparable)k).compareTo(x));
    }
/*
* 計算返回table的size,結果值爲大於或等於cap的最小2的冪次
*/

    static final int tableSizeFor(int cap) {
// 計算前減1,防止cap已經是2的冪次時獲取的值爲cap*2
        int n = cap - 1;
//以下操作即將cap的二進制值後續值全部補1,如01000010,則補充後爲01111111
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
//返回計算值+1,得到大於等於cap的最小2冪次值
        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
    }
// 存儲鏈/樹的表格,首次使用時初始化大小,且大小必須爲2的冪次
    transient Node<K,V>[] table;
//存儲值的集合,用於keySet() 和 values()方法
    transient Set<Map.Entry<K,V>> entrySet;
// hashmap實際存儲的節點數,put或remove等操作時都會更新
    transient int size;
//每次成功調整hashmap結構時增加一次,主要用於防止在map上建立子視圖時進行調整結構操作
    transient int modCount;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章