日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

HashMap之扰动函数和低位掩码

發布時間:2025/3/15 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HashMap之扰动函数和低位掩码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

我們都知道,hashMap在實現的時候,為了尋找在數組上的位置,主要做了兩件事

int hash = hash(key); int i = indexFor(key, table.length);

這個時候得到i才是數組上的位置。

?

這兩個方法詳解如下

JDK8對擾動函數的修改,只進行了一次移位(又移16bit),再和key.hashCode()做異或,如圖

static final int hash(Object key){ int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }

這個散列值是不能直接拿來用的。用之前還要先做對數組的長度取模運算,得到的余數才能用來訪問數組下標。源碼中模運算是在這個indexFor( )函數里完成的。

bucketIndex = indexFor(int h, table.length);

其中IndexFor代碼

1 static int indexFor(int h, int length){ 2 return h & (length - 1); 3 }

indexFor代碼,正好解釋了為什么HashMap的數組長度要取2的整次冪。因為這樣(數組長度-1)正好相當于一個“低位掩碼”。“與”操作的結果就是散列值的高位全部歸零,只保留低位值,用來做數組下標訪問。以初始長度16為例,16-1=15。2進制表示是00000000 00000000 00001111。和某散列值做“與”操作如下,結果就是截取了最低的四位值。

但這時候問題就來了,這樣就算我的散列值分布再松散,要是只取最后幾位的話,碰撞也會很嚴重。更要命的是如果散列本身做得不好,分布上成等差數列的漏洞,恰好使最后幾個低位呈現規律性重復,就無比蛋疼。

這時候“擾動函數”的價值就體現出來了,說到這里大家應該猜出來了。看下面這個圖,

右位移16位,正好是32bit的一半,自己的高半區和低半區做異或,就是為了混合原始哈希碼的高位和低位,以此來加大低位的隨機性。而且混合后的低位摻雜了高位的部分特征,這樣高位的信息也被變相保留下來。

JDK 7做了4次右移,估計是邊際效應的原因,JDK8就只做了一次右移。

另外 JDK8在鏈表長度超過8的時候,就使用紅黑樹做存儲。這一改變大大優化了很多性能。

轉載于:https://www.cnblogs.com/lycroseup/p/7344321.html

總結

以上是生活随笔為你收集整理的HashMap之扰动函数和低位掩码的全部內容,希望文章能夠幫你解決所遇到的問題。

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