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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

面试高频问题:HashMap实现原理

發(fā)布時間:2023/12/20 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 面试高频问题:HashMap实现原理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

2019獨角獸企業(yè)重金招聘Python工程師標準>>>

今天給同學(xué)們講講一個面試經(jīng)常遇到的高頻問題,HashMap實現(xiàn)原理,希望在金三銀四的季節(jié)對同學(xué)們有幫助。

HashMap結(jié)構(gòu)圖目錄
?一、嘮叨
?二、解析思路

?三、get方法
?四、put方法
?五、resize方法

?一、嘮叨


認真閱讀了下HashMap的實現(xiàn)方式,也參考了網(wǎng)上別人的一些解析,個人覺得還是有些東西想說。網(wǎng)上有的文章名字為HashMap源碼解析,實際上就是給它里面的一些方法加上一些注釋而已,有不少都是這樣的。
我自己看源碼的時候,發(fā)現(xiàn)不是別人不想解析,而是它的實現(xiàn)真的需要親自研讀,多理順幾遍才知道怎么回事。
我在這里解析的文字描述也較多,不管誰的解析,自己也都要看一下JDK源碼的具體實現(xiàn),我們僅提供參考而已。

二、解析思路


源碼不太方便看,先說明一下我的閱讀思路。
1.把常用的幾個方法拷貝到文本編輯器里面。
2.HashMap中不同的時候會有不同的流程,梳理方法中的邏輯流程。就像采用極端法,采用特殊的數(shù)據(jù),然后查看方法執(zhí)行語句。未執(zhí)行的語句暫時不考慮。
3.注釋源碼...我覺得HashMap的實現(xiàn)方式不夠好,關(guān)鍵的幾個方法里面包含的情況太多了,閱讀起來是有難度的,而寫程序的目的之一不就是讓其他開發(fā)者閱讀嗎?一個方法內(nèi)部做了太多的事情,違反了代碼整潔的規(guī)則,一個函數(shù)做要盡量少的事情。
解析
之前稍微介紹了一些HashMap的特性,HashMap初探。
(https://www.jianshu.com/p/be9ffb76db30)這里接著深入。

三、get方法

先挑最簡單的說

?

?

1 先從數(shù)組下標,找到對應(yīng)的Node2.?
2 如果Node里的第一個節(jié)點命中,直接返回
3 如果有沖突,則通過key.equals(k)去查找對應(yīng)的entry
4 若為樹,則在樹中通過key.equals(k)查找,O(logn);
5 若為鏈表,則在鏈表中通過key.equals(k)查找,O(n)。put方法這個中間涉及的邏輯多一些,方法需要分不同的步驟看。

?


?

四、put方法


這個中間涉及的邏輯多一些,方法需要分不同的步驟看。
思路:
1對key的hashCode()做hash,然后再計算index;
2如果沒碰撞直接放到bucket里;
3如果碰撞了,以鏈表的形式存在buckets后;
4如果節(jié)點已經(jīng)存在就替換old 5value(保證key的唯一性)
6如果碰撞導(dǎo)致鏈表過長(大于等于TREEIFY_THRESHOLD),就把鏈表轉(zhuǎn)換成紅黑樹;
7如果Node的容量滿了(超過load factor*current capacity),就要resize。



?

一般不發(fā)生碰撞的時候,相對簡單,數(shù)據(jù)量較小的情況下。

?

?

我解釋下關(guān)于碰撞沖的循環(huán)。
1.查看是否存在相同的key,存在相同的key跳出循環(huán),覆蓋key的value。
2.如果不存在相同的key,在鏈表末尾插入新的Node如果鏈表節(jié)點過長,轉(zhuǎn)換為樹。
3.如果鏈表節(jié)點過長,轉(zhuǎn)換為樹。

?

?

紅黑樹的部分,我們下次單獨解析

?五、resize方法


這個涉及的內(nèi)容,有不少線需要捋一捋。首先看申明時候會resize()。它們都在調(diào)用put的時候執(zhí)行的。

1.table == 的時候

?

?

2.鍵值映射的的數(shù)目大于臨界值的時候。

?

?

六、resize具體方法


?

?

如果是第一次resize,我們抽出來會執(zhí)行到的語句。
1.初始化容量
2.初始化threshold,也就是初始化臨界值,決定了table的鍵值對數(shù)目到什么時候會再次resize()


?

第二次及后續(xù)的resize執(zhí)行流程

?


?

resize中對有碰撞的鏈表的操作寫的很有意思,再敘述一下。在重新分配索引的時候,有重新組建鏈表的操作。

舉個比較夸張的例子,讀者就明白了。
1.e.hash < 2,那么e.hash&oldCap就等于0,索引為小于之前hash表大小以內(nèi)的索引。也就是當(dāng)初的索引不變。
2.e.hash > 2的時候,e.hash&old不等于0,那么它的索引就為當(dāng)前表的索引再加上新擴容的大小。


? ? ? ? ? ? ? ? 案例圖

這個圖說的是,當(dāng)hashmap的表大小為2擴充到4的時候,原本掛載在1位置的鏈表,重新分配之后的樣子。

最后
篇幅有限,我這里僅僅介紹了get方法,put方法,resize方法的具體原理,文章就已經(jīng)非常長了,不利于閱讀。
下次再補充一下HashMap的hash方法原理,其余的相關(guān)注意事項。

轉(zhuǎn)載于:https://my.oschina.net/u/4118408/blog/3054746

總結(jié)

以上是生活随笔為你收集整理的面试高频问题:HashMap实现原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。