本篇內(nèi)容介紹了“HashMap的介紹以及擴(kuò)容為什么是2的n次冪”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
創(chuàng)新互聯(lián)專注于網(wǎng)站建設(shè),為客戶提供做網(wǎng)站、成都網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)開發(fā)服務(wù),多年建網(wǎng)站服務(wù)經(jīng)驗(yàn),各類網(wǎng)站都可以開發(fā),品牌網(wǎng)站制作,公司官網(wǎng),公司展示網(wǎng)站,網(wǎng)站設(shè)計(jì),建網(wǎng)站費(fèi)用,建網(wǎng)站多少錢,價(jià)格優(yōu)惠,收費(fèi)合理。
1.什么是HashMap?
HashMap是Java中的集合類,是存放鍵值對(duì)形式的數(shù)據(jù)(Key和Value),例如QQ賬號(hào)和QQ密碼,QQ賬號(hào)就是Key而密碼則是Value。如下圖所示(假如QQ賬號(hào)為123456,密碼為abcdef)
運(yùn)行結(jié)果如下所示
如果存放相同的Key,那么Value將會(huì)被覆蓋,類似于QQ更改密碼,賬號(hào)不會(huì)變,只有密碼會(huì)進(jìn)行更改。
運(yùn)行結(jié)果如下所示
2.為什么擴(kuò)容2的n次冪?
首先先看一下HashMap中的putVal方法(存值的)和resize方法(擴(kuò)容的),之所以HashMap擴(kuò)容是2的n次冪和這兩個(gè)方法有千絲萬縷的聯(lián)系。
通過putVal方法可以看出來HashMap在存值時(shí)會(huì)先把key的hash值和擴(kuò)容后的長(zhǎng)度進(jìn)行一次按位與運(yùn)算,其中hash是在hash方法中把key進(jìn)行計(jì)算后的出來的結(jié)果,n是擴(kuò)容的長(zhǎng)度(也就是數(shù)組的長(zhǎng)度,默認(rèn)為16),然后判斷是否hash碰撞在進(jìn)行不同的存儲(chǔ)。如下圖源碼所示。
通過resize方法可以看出來擴(kuò)容時(shí)會(huì)新建一個(gè)tab,然后遍歷舊的tab,將舊的元素進(jìn)行e.hash & (newCap - 1)的計(jì)算添加進(jìn)新的tab中,也就是(n - 1) & hash的計(jì)算方法,其中n是集合的容量,hash是添加的元素經(jīng)過hash函數(shù)計(jì)算出來的hash值。如下圖源碼所示。
之所以這樣2n擴(kuò)容和上面的兩個(gè)方法有極大的關(guān)系,首先他們都使用了按位與運(yùn)算,按位與運(yùn)算就是把值先變成二進(jìn)制然后進(jìn)行運(yùn)算,如果有0則為0,都為1時(shí)則輸出為1,HashMap默認(rèn)容量為16那么在存放到數(shù)組時(shí)就是n-1也就是15,而15二進(jìn)制則是1111擴(kuò)容后為32-1及11111111
,如果都為1的情況下是可以極大的減少hash碰撞,增加效率的。
通過下面例子來看一下當(dāng)容量為11111111時(shí)按位與運(yùn)算的結(jié)果,通過下面的結(jié)果可以看出來結(jié)果很分散,大大減少了hash碰撞的發(fā)生。
再看一下當(dāng)容量不為11111111而是為其他值的時(shí)候,通過下面的結(jié)果可以看出,1、2、4跟不同的值進(jìn)行hash運(yùn)算但是結(jié)果卻是相同的,也就是發(fā)生了hash碰撞。
通過上面的對(duì)比可以看出來11111111和其他值比較大大的減少了hash碰撞的發(fā)生,這樣就是為什么HashMap為什么擴(kuò)容采用2的n次冪的原因。
“HashMap的介紹以及擴(kuò)容為什么是2的n次冪”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!