天天看點

面試官經常被問到的問題,Java中的HashMap

想必經曆過面試的人很多都能被問到這個問題,當然小編也不例外,今天就給大家剖析一下HashMap在jdk1.8中的結構及其使用,分享在這,從中自己也在學習,不斷積累技術和大家一起分享。

一:概述

       HashMap最早在jdk1.2中就存在了,HashMap繼承自父類(AbstractMap),實作了Map、Cloneable、Serializable接口,底層思想是基于雜湊演算法實作的,HashMap可以用null作為鍵,也可以用null作為值,當存儲的鍵為null時,對應計算的結果是0,用0作為鍵值的,HashMap不是線程安全的,如果使用HashMap要滿足線程安全,可以使用Collectio類的的synchronizedMap方法使HashMap具有線程安全的能力,或者使用ConcurrentHashMap類。

一:資料的存儲結構

      在jdk1.7中的HashMap中的資料結構是數組+單連結清單的組合,使用連結清單處理hash值沖突的元素,而存在的問題就是當hash鍵值相等的情況較多時,都會将值儲存在一個單連結清單上,也就是其中的一個桶中,導緻通過key值去查找效率很低,是以在jdk1.8中,HashMap采用了數組+連結清單+紅黑樹來實作,這在結構上與jdk 1.7最大的不同,而在jdk1.8中,如果hash鍵值沖突較多時,單連結清單的長度超過規定的臨界值(8)時,就會将連結清單轉換成紅黑樹的結構存儲,這樣就能高效的查詢,提高HashMap的查詢效率。

       1. HashMap成員變量:   

             * The default initial capacity - MUST be a power of two.

             *  預設HashMap初始化的容量為16,且長度必須為2的幂等

             */

            static final int DEFAULT_INITIAL_CAPACITY = 16;

         /**

             * The table, resized as necessary. Length MUST Always be a power of two.

                * 數組是存儲HashMap的連結清單表頭

             */

            transient Entry<K,V>[] table;

            /** 最大初始容量,2^30 */      
            static final int MAXIMUM_CAPACITY = 1 << 30;      
           /** 負載因子,預設0.75,負載因子越小,hash沖突機率越低 */      
          static final float DEFAULT_LOAD_FACTOR = 0.75f;      
          /** 初始化一個Entry的空數組 */      
          static final Entry<?,?>[] EMPTY_TABLE = {};      
          /** HashMap實際存儲的元素個數 */      
          transient int size;      
          /** 臨界值(HashMap 實際能存儲的大小),公式為(threshold = capacity * loadFactor) */      
          int threshold;      
          /** 負載因子 */      

         final float loadFactor;

          /** HashMap的結構被修改的次數,用于疊代器 */      

         transient int modCount;

2:HashMap的數組結構

面試官經常被問到的問題,Java中的HashMap

圖1

3:紅黑樹結構及性質介紹

     紅黑樹其實就是一種自平衡的二叉查找樹,他這個自平衡的特性就是針對HashMap中連結清單可能會很長,做出的優化。紅黑樹是每個節點都帶有顔色屬性的二叉查找樹,顔色或紅色或黑色。在二叉查找中有的性質外,紅黑樹也有自己的特點:

特點1. 節點都是紅色或黑色,是以稱為紅黑樹。

特點2. 樹的根節點是黑色。

特點3. 每個葉節點(NIL節點,空節點)是黑色的。

特點4. 每個紅色節點的兩個子節點都是黑色。(從每個葉子到根的所有路徑上不能有兩個連續的紅色節點)

特點5. 從任一節點到其每個葉子的所有路徑都包含相同數目的黑色節點。

static final class TreeNode<k,v> extends LinkedHashMap.Entry<k,v> {      
    TreeNode<k,v> parent;  // 父節點      
    TreeNode<k,v> left; //左子樹      
    TreeNode<k,v> right;//右子樹      
    TreeNode<k,v> prev;    // needed to unlink next upon deletion      
    boolean red;    //顔色屬性      
    TreeNode(int hash, K key, V val, Node<k,v> next) {      
        super(hash, key, val, next);      

    } 

面試官經常被問到的問題,Java中的HashMap

4:HashMap的擴容機制