日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

hashmap扩容 面试_HashMap面试,看完这一篇就够了(上)

發布時間:2023/12/4 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hashmap扩容 面试_HashMap面试,看完这一篇就够了(上) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

以下HashMap源碼的解析都是基于java8來講解的。

HashMap的結構是數組加鏈表的形式(jdk7中也是),在java8中引入了紅黑樹,由于紅黑樹的時間復雜度是O(log n),引入紅黑樹是為了解決在哈希沖突很嚴重的時候導致鏈表太長,從而引起的查找效率太低的問題。

常量

※ 為什么鏈表長度大于8才進行樹化

源碼中有下面一段解釋

大體意思就是:由于TreeNode所占空間是普通Node的兩倍,所以只有在bin包含足夠多的node的時候才會轉化為Tree(有TREEIFY_THRESHOLD決定)。當bin變的很小的時候,又會轉為鏈表。當hashCode分布良好的時候,幾乎用不到tree,hash沖突很小。但是在隨機hashCode時,離散性差,會導致hash沖突嚴重,所以導致鏈表很長,這時候就要轉化為紅黑樹來提高查詢效率。按上面java官方給出的概率,鏈表長度達到8的概率是0.00000006,是很低很低的概率了,所以java也是通過大概率統計得出大于8的時候才轉化為紅黑樹。

內部類 Node

從java8開始,HashMap的節點改為了使用Node(java7使用Entry),其實都差不多,內部結構都類似。

hash hash值key key值value value值next 下一個節點方法

put方法

put方法調用了下面的putVal方法,這里和java7版本的不同有兩處:

當鏈表長度大于8的時候,會轉化為紅黑樹;而且如果Node是TreeNode類型,則按照紅黑樹的方式進行putput采用的是尾插法,這樣在擴容的時候避免了多線程情況下出現死循環(java7采用頭插法,會存在擴容時出現死循環)

get方法

get方法調用了getNode方法

HashMap擴容

HashMap的擴容存在的問題也是面試中經常問到的,首先來看下擴容的源碼

在這段代碼中,java8進行了優化的,一部分是元素位置不變的,一部分是元素位置+old capacity。它是這樣實現的:

e.hash & oldCap

這段代碼不是為了判斷元素所在的位置,而是判斷hash值在old capacity的那一位是不是0,舉個例子:hashCode是20,old capacity是16,new capacity是32,計算元素位置的方式:(n - 1) & hash

擴容前后對比發現,差距就在old capacity二進制1的位置那,所以e.hash & oldCap可以判斷出那個位置是否為1。如果為1,那么元素的新位置就是old capacity+擴容前的元素位置 即為擴容后的位置;如果為0,則擴容后的位置與擴容前相同。java8之所以這樣優化,首先是因為HashMap的capacity始終是2的冪次方,這樣就保證了e.hash & oldCap的正確性;其次這樣優化去掉了擴容時的重新hash運算,提高了效率。

擴容存在的問題

數據覆蓋看resize源碼可以發現,當兩個線程同時走到#1的位置時,如果線程1和線程2的key的hash值相同,那線程1賦值后讓出cpu,此時線程2獲得時間片,同樣也進行了賦值操作,那么線程1賦的值就被線程2給覆蓋掉了。死循環在java8中已經不存在死循環了。但是在java7中是存在的。有與java7是頭插法,所以在resize的時候,鏈表的順序會反轉,此時兩個線程同時進行resize,就有可能形成鏈式的圓圈,造成死循環。HashMap線程不安全,那該用什么

HashMap的線程版本有HashTable和Collections.synchronizedMap(map),但是這兩個都是直接加synchronized實現的,效率很低。而HashMap的線程安全版本常用的是ConcurrentHashMap,這個也是面試中經常問到的。明天會更新ConcurrentHashMap的相關面試點,歡迎大家繼續關注。

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的hashmap扩容 面试_HashMap面试,看完这一篇就够了(上)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。