底層是陣列+鍊錶+紅黑樹,集陣列和鍊錶的優點與一身,執行緒不安全。
在新建乙個hashmap時,會初始化乙個陣列,在jdk1.8之前初始化的陣列初始容量為16,但在jdk1.8及之後,它實現了乙個懶載入功能,就是在第一次put資料時才會初始化容量,初始容量仍然是16,在新增資料時,新增資料的下標是由key經過hash演算法生成的,獲取的hash值與陣列長度進行乙個取餘演算法獲取下標,取餘不是用『%』,而是用『&』,因為『&』的運算比『%』快,而且用陣列的長度肯定是2的次冪,所以不用擔心『%』和『&』這倆個算出的值不相等的問題(只有長度為2的次冪時,『%』和『&』的結果才肯定相等)。在容量達到當前容量的0.75倍時,陣列會進行擴容,規則是擴容為原來的2倍,比如當前容量為16,當新增第13個資料時,陣列就會進行擴容,擴容後所有key重新進行hash演算法重新獲取自己的『房子』
在新增資料時,當hash演算法算出新key的值與陣列中某個key一致時,會觸發鍊錶結構,相當於在老key旁邊放乙個小板凳讓新key坐,如圖所示
當鍊表的長度大於等於8時會鍊錶會轉成紅黑樹,當它長度再次小於6之後會再轉為鍊錶,否則仍以紅黑樹儲存資料,在這裡有個重點,就是當陣列的長度小於64時,鍊錶是不會轉為紅黑樹的,因為當陣列長度小於64,使用陣列加鍊錶比使用紅黑樹查詢速度要更快、效率要更高。
HashMap底層資料結構之鍊表轉紅黑樹的具體時機
1 從hashmap中有關 鍊錶轉紅黑樹 閾值的宣告 2 重點 解析hashmap.put k key,v value 的原始碼 3 測試 hashmap中有關 鍊錶轉紅黑樹 閾值的宣告 使用紅黑樹 而不是鍊錶 來存放元素。當向至少具有這麼多節點的鍊錶再新增元素時,鍊錶就將轉換為紅黑樹。該值必須大於...
Redis底層資料結構 鍊錶
這是普通的鍊錶實現,鍊錶結點不直接持有資料,而是通過void 指標來間接的指向資料.其實現位於src adlist.h與src adlist.c中,關鍵定義如下 typedef struct listnode listnode typedef struct listiter listiter typ...
使用鍊錶 陣列,手寫HashMap
在jdk1.7版本的hashmap 底層採用了鍊錶 陣列的方式實現資料的儲存及擴容等,在jdk1.8後hashmap的底層換為紅黑樹 陣列的方式。這邊以鍊錶 陣列的方式模仿原始碼寫乙個自己的簡易hashmap。其中初始容量設為的10,負載因子設定0.5,上面效果已有了擴容的效果。因為是基於鍊錶 陣列...