HashMap原始碼深入的理解和每個方法的逐步分析

2021-08-21 15:24:49 字數 1905 閱讀 5646

public v put(k key, v value) 

}modcount++;

//將key value 新增到 索引i處

addentry(hash, key, value, i);

return null;

}

分析上面的原始碼,我們可以得到下面的結論:

當我們試圖將乙個key-value 呼叫put方法放入hashmap的時候,首先會呼叫key的hashcode方法算出該entry存放的位置,若兩個key的hashcode相同則在table中的儲存位置相同,則先呼叫equals方法判斷兩個key是否相同,相同則覆蓋,不相同則產生乙個entry鍊錶(因為table陣列中乙個索引位置只能放入乙個entry,所以當有多個key的hashcode相同時,這些key就會以鍊錶的形式存在,並且最後put進來的key在鍊錶的最前面)

然後則是hashmap的構造方法,這裡以 hashmap(int initialcapacity, float loadfactor)這個構造器為例,原始碼如下

public hashmap(int initialcapacity, float loadfactor)
從上面的原始碼可以看出 ,初始容量不能為負數,若初始容量大於最大容量,則讓它等於最大容量,負載因子必須大於0,並且傳入的initialcapacity不是hashmap的容量大小,

實際容量大小的計算規則是大於傳入的initialcapacity的最小的2的n次方,比如傳入的initialcapacity是5 那麼實際容量則是8 因為2的3次方大於5。

下面再分析一下hashmap的儲存效能,下面的 get方法的原始碼

public v get(object key) 

final entrygetentry(object key)

return null;

}

再次強調一下table的概念,table就是當我們初始化乙個hashmap時,會自動建立乙個長度為capacity的entry陣列,我們把這個陣列存放元素的位置叫「桶」,並且每個桶只儲存乙個entry元素(也就是我們的鍵值對),並且當我們put乙個鍵值對時,先計算key的hashcode來判斷這個鍵值對會放入哪乙個桶,所以若多個key的hashcode相同時,他們都要被放入乙個桶裡面,但是乙個桶裡面只能放入乙個entry(鍵值對),要解決這個問題先看下面的**

entry(int h, k k, v v, entryn)
這是entry的構造方法,我們可以看出entry物件包含乙個entry的引用,用來指向下乙個entry,這樣就解決了hashcode相同,存放衝突的問題,所以當有多個key的hashcode相同時,就會形成乙個entry鏈,我們從get方法可以看出當系統通過key的hashcode找到了對應的桶的時候,會遍歷這個entry鏈,來找到我們要取的value的key,這個時候,若剛好這個entry在鍊錶的末端(也就是我們最開始put進去的entry)那麼當這個鍊錶太長了,勢必會影響我們的查詢效能,這個時候就引出了loadfactor(負載因子的說法),hashmap的預設附在因子是0.75,我對負載因子的理解就是,表示hashmap在什麼時候擴容,也就是說若我們初始的hashmap容量是16 負載因子是0.75,那麼當有12個「桶」有了entry時,hashmap

就會擴容,並且擴大的容量是原來容量的2倍,為什麼是12呢?因為0.75x16=12。並且負載因子是可以更改的,修改它的前提是如果記憶體比較緊張就可以適當的增加負載因子,

若空間,記憶體比較充足,更關注查詢效率則減少負載因子。為什麼會這樣呢?因為若負載因子減少了,比如說減少到了0.5,預設hashmap容量大小還是16,那麼當我有8個"桶"中存放了entry陣列時我就會擴容了,該桶裡的entry鏈相比於之前就不會那麼長,從而提公升了查詢效能。

今天先到這裡,下次再寫。

HashMap原始碼理解

map子類常用有 hashmap 無序 和treemap 有序 hashmap hashmap的特點 無序 hash 執行緒不安全,陣列 鍊錶實現 對應的hashtable加了同步鎖 synchronized同步鎖 執行緒安全 hashmap底層是 陣列 鍊錶實現的,陣列下下標存放的是hashcod...

hashmap原始碼理解

在jdk1.8之前是資料 鍊錶方式存 在這裡插入 片 儲,從jdk 1,8開始以資料 鍊錶 紅黑樹方式儲存,具體的儲存方式時根據key來hash碰撞計算key的hash值,來找到對應的陣列中的下標,在判斷鍊錶的next儲存,當單個鍊錶多於8個,並且總的數多於64是啟動resize從新排序,此時才加入...

HashMap原始碼系列 HashMap的屬性

public class hashmap extends abstractmap implements map,cloneable,serializable容載因子 容載因子越大,table陣列中儲存的資料越密集,碰撞的可能性就越大。容載因子越小,儲存越稀疏,碰撞的可能性就越小,不過浪費儲存空間。轉...