HashMap剖析之內部結構

前言

本文是基於Java 8HashMap進行分析,主要是介紹HashMap中的成員變量和類變量的用途,以及分析HashMap的數據結構。

變量分析

HashMap中存在多個成員變量和類變量,搞清楚它們的用途有助於我們更深入瞭解HashMap,下面是它們的介紹:

    /**
     * 默認的初始容量,必須爲2的次冪
     */
    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // 總所周知是16

    /**
     * 最大容量
     */
    static final int MAXIMUM_CAPACITY = 1 << 30;

    /**
     * 默認的負載因子
     */
    static final float DEFAULT_LOAD_FACTOR = 0.75f;

    /**
     * 將鏈表轉化爲紅黑樹的閾值,當鏈表節點數大於或等於該閾值-1則轉化爲紅黑樹
     */
    static final int TREEIFY_THRESHOLD = 8;

    /**
     * 將紅黑樹轉化爲鏈表的閾值,當紅黑樹的節點小於該閾值時轉化爲鏈表
     */
    static final int UNTREEIFY_THRESHOLD = 6;

    /**
     * 允許進行鏈表轉化爲紅黑樹的閾值,只有散列表大小大於或等於該值才能進行紅黑樹轉化
     */
    static final int MIN_TREEIFY_CAPACITY = 64;
    /**
     * HashMap中存儲數據的數組,也稱爲散列表。
     * 建議保持長度爲2的次冪
     */
    transient Node<K,V>[] table;

    /**
     * 緩存entrySet()方法的值
     */
    transient Set<Map.Entry<K,V>> entrySet;

    /**
     * Map中鍵值對的個數
     */
    transient int size;

    /**
     * HashMap數據結構被改變的次數,一般是指散列表的長度改變、Node鏈表增加或者減少節點
     * 這個參數是用於快速失敗機制
     */
    transient int modCount;

    /**
     * 下一次觸發調整大小(resize()方法)的閾值,一般爲容量乘以負載因子 
     */
    int threshold;

    /**
     * 散列表的負載因子,用於計算擴容的閾值
     */
    final float loadFactor;

數據結構

HashMap使用拉鍊法解決哈希表中存在的哈希衝突問題,所以HashMap底層是用以Node組成的鏈表爲元素的數組table來存儲鍵值對,每個Node就是一個鍵值對對象。table稱呼爲散列表。

table對應的是散列表,是因爲無論是存儲還是讀取鍵值對的時候,都會對key進行hash%table.length運算來進行散列表的命中,然後操作命中的索引對應的Node鏈表(還是會比較keyhash)。

以上爲Java 8之前版本的HashMap的實現,而Java 8進行了優化:就是當鏈表節點數超過閾值TREEIFY_THRESHOLD(8)時,則會將鏈表轉化爲紅黑樹

如果只是使用文字描述的話會很難理解,所以下面會通過一幅圖展示:

5c617b6ee4b0f0908a90b1b5.png

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