HashMap詳解

源碼:HashMap,Mybatis,Spring 建議看

 

HashMap: 數組+鏈表+(1.8之後紅黑樹)

 

Object類的hashCode:返回對象的內存地址經過處理後的結構,由於每個對象的內存地址都不一樣,所以哈希碼也不一樣

 

static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

初始容量:1<<4 即 16.     

問 爲什麼初始容量 是16?

答:java的底層是c語言,C語言底層是彙編語言,彙編再往上就是機器語言,彙編編程使用的就是16進制,因此效率越高。

 

內部結構

有一個Node類

Node Implement Map.entry{
    hash
    key
    value
    next
}

Map.entry

interface Entry<K,V> {
    getKey()
    setKey()
    getValue()
    setValue()
    比較器,hash等抽象或具體實現的方法
}

當數據傳進來時,首先會封裝成Node,根據key取hash值,然後 hash(key) &(length()-1) ,存入數據

哈希衝突/碰撞:

1 單向鏈表:

    1.8之前 可以無限掛,1.8之後只能掛7個,第8個的時候轉變爲紅黑樹。最大容量爲64,達到64再拆分。大於64會擴容。

    下掛節點<=6個,會將紅黑樹再轉變爲鏈表

問:爲什麼是6個時候轉變?不是7個呢?

答:7個做準備,多一個是紅黑樹,少一個鏈表

/**
     * The bin count threshold for untreeifying a (split) bin during a
     * resize operation. Should be less than TREEIFY_THRESHOLD, and at
     * most 6 to mesh with shrinkage detection under removal.
     */
    static final int UNTREEIFY_THRESHOLD = 6;
/**
     * The smallest table capacity for which bins may be treeified.
     * (Otherwise the table is resized if too many nodes in a bin.)
     * Should be at least 4 * TREEIFY_THRESHOLD to avoid conflicts
     * between resizing and treeification thresholds.
     */
    static final int MIN_TREEIFY_CAPACITY = 64;

 

 

擴容因子0.75    

初始容量16,當存到12時,會擴容成32容量

問:hashMap的擴容怎麼操作的?擴容後的元素如何均分的?

答:非常巧妙的處理:

0101 0101 0101 0101 0101 0101 0101 0101 = 每個Node的hash(key)值

0000 0000 0000 0000 0000 0000 0001 0000 = 32 容量

第五位若是0,則不變,若是1,則 當前位置 = 當前位置 +上一個容量 

/**
     * The load factor used when none specified in constructor.
     */
    static final float DEFAULT_LOAD_FACTOR = 0.75f;

 

 

 

 

 

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