HashMap底層數據結構及其增put刪remove查get方法的代碼實現原理

1.HashMap底層數據結構是數組+鏈表(jdk1.7頭插法<擴容時鏈表逆序可能會導致環形鏈表的問題出現> jdk1.8尾插法)+紅黑樹(jdk1.8).
2.HashMap中數組的容量默認爲16,負載因子默認爲0.75,當數組的0-15個下標裏有16×0.75=12個被使用時,且HashMap中存儲的元素總個數大於64時,則發生擴容操作,數組的容量擴大爲原來的2n.
3.負載因子代表數組中存儲數據密度的大小:負載因子越大,數組單位容量內存儲的數據越多,不同元素之間(key不同,但計算得到的數組下標相同)越容易發生碰撞(哈希碰撞);反之,則單位容量內存儲的數據越少,越不易發生碰撞.
4.put(key,value)時的處理邏輯:
(1)hash(key) = (key==NULL)?0:(h=key.hashCode())^(h>>>16),即取key的原始哈希碼的高低16位進行異或位運算,計算出一個經高低位混合後高低位分佈更加均勻的新哈希碼,再用該新哈希碼和數組容量減一做與位運算(hash(key)&(2^n-1))得出要存放的數組下標[當HashMap的容量是2的n次冪時,(2^n-1)的二進制就是11111*111全1的形式,這樣與hash(key)進行與的位運算時,能夠充分的散列,使得添加的元素均勻分佈到HashMap的每個位置上,減少hash碰撞],可以一定程度降低根據不同元素計算得出相同數組下標(哈希碰撞)的概率;
(2)得出的數組下標裏已經存放有數據元素,則根據key的值遍歷比較該下標下的鏈表或紅黑樹,如果遇到相同key,則更新key對應的value值後返回(return);若遍歷鏈表後未遇到相同的key,則在鏈表(jdk1.7頭部 jdk1.8尾部)或紅黑樹合適位置(可能觸發紅黑樹的左旋右旋或顏色改變),插入新的(key,value)鍵值對元素(插入值時統計存儲的總元素個數的變量值會加一) ;
(3)某鏈表插入新的鍵值對後,可能導致該鏈表的長度大於等於8,若此時數組存儲的總元素個數大於等於64,則將鏈表轉爲紅黑樹(保證最好最壞情況下時間複雜度爲以2爲底總元素個數n的對數級別,以提高增刪查處理性能);
(4)鏈表插入新值後,也可能會觸發數組擴容操作
5.get(key)時的處理邏輯:同put(key,value)的步驟(1),會根據key值計算得出數組下標,然後用key值遍歷比較該數組下標下的鏈表或或紅黑樹,找到相同key對應的value值並返回,否則,返回null;
6.remove(key)時的處理邏輯:同get(key)和put(key,value)的步驟(1),會先根據key找到要刪除元素所在位置,然後進行刪除操作;

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