一文看懂HashMap擴容爲何是2的n次冪

1.什麼是HashMap?

    

    HashMap是Java中的集合類,是存放鍵值對形式的數據(Key和Value),例如QQ帳號和QQ密碼,QQ帳號就是Key而密碼則是Value。以下圖所示(假如QQ帳號爲123456,密碼爲abcdef)數組



    

    運行結果以下所示微信





    若是存放相同的Key,那麼Value將會被覆蓋,相似於QQ更改密碼,帳號不會變,只有密碼會進行更改。less





    運行結果以下所示編輯器

    




2.爲何擴容2的n次冪?



    首先先看一下HashMap中的putVal方法(存值的)和resize方法(擴容的),之因此HashMap擴容是2的n次冪和這兩個方法有千絲萬縷的聯繫。函數



    經過putVal方法能夠看出來HashMap在存值時會先把key的hash值和擴容後的長度進行一次按位與運算,其中hash是在hash方法中把key進行計算後的出來的結果,n是擴容的長度(也就是數組的長度,默認爲16),而後判斷是否hash碰撞在進行不一樣的存儲。以下圖源碼所示。spa





    經過resize方法能夠看出來擴容時會新建一個tab,而後遍歷舊的tab,將舊的元素進行e.hash & (newCap - 1)的計算添加進新的tab中,也就是(n - 1) & hash的計算方法,其中n是集合的容量,hash是添加的元素通過hash函數計算出來的hash值。以下圖源碼所示。.net





    之因此這樣2n擴容和上面的兩個方法有極大的關係,首先他們都使用了按位與運算按位與運算就是把值先變成二進制而後進行運算,若是有0則爲0,都爲1時則輸出爲1,HashMap默認容量爲16那麼在存放到數組時就是n-1也就是15,而15二進制則是1111擴容後爲32-1及111111113d

,若是都爲1的狀況下是能夠極大的減小hash碰撞,增長效率的。blog



    經過下面例子來看一下當容量爲11111111時按位與運算的結果,經過下面的結果能夠看出來結果很分散,大大減小了hash碰撞的發生。
ip


    再看一下當容量不爲11111111而是爲其餘值的時候,經過下面的結果能夠看出,一、二、4跟不一樣的值進行hash運算可是結果倒是相同的,也就是發生了hash碰撞。


    經過上面的對比能夠看出來11111111和其餘值

比較大大的減小了hash碰撞的發生,這樣就是爲什

麼HashMap爲何擴容採用2的n次冪的緣由。




本文分享自微信公衆號 - 大貓的Java筆記(damaoJava)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索