hashcode使用31作為乘法因子的原因小記

2021-09-17 07:13:53 字數 503 閱讀 8681

31是質子數中乙個「不大不小」的存在,如果你使用的是乙個如2的較小質數,那麼得出的乘積會在乙個很小的範圍,很容易造成雜湊值的衝突。而如果選擇乙個100以上的質數,得出的雜湊值會超出int的最大範圍,這兩種都不合適。而如果對超過 50,000 個英文單詞(由兩個不同版本的 unix 字典合併而成)進行 hash code 運算,並使用常數 31, 33, 37, 39 和 41 作為乘子,每個常數算出的雜湊值衝突數都小於7個(國外大神做的測試),那麼這幾個數就被作為生成hashcode值得備選乘數了。

jvm裡最有效的計算方式就是進行位運算了:

* 左移 << : 左邊的最高位丟棄,右邊補全0(把 << 左邊的資料*2的移動次冪)。

* 右移 >> : 把》左邊的資料/2的移動次冪。

* 無符號右移 >>> : 無論最高位是0還是1,左邊補齊0。   

所以 : 31 * i = (i << 5) - i(左邊  31*2=62,右邊   2*2^5-2=62) - 兩邊相等,jvm就可以高效的進行計算啦。。。

定義hashcode時使用31係數的原因

雜湊計算就是計算元素應該放在陣列的哪個元素裡。準確的說是放到哪個鍊錶裡面。按照j a的規則,如果你要想將乙個物件放入hashmap中,你的物件的類必須提供hashcode方法,返回乙個整數值。比如string類就有如下方法 public int hashcode bfbqtbe hash h ret...

為什麼在定義hashcode時要使用31這個數呢?

public int hashcode hash h return h 該函式是我看的函式介面原始碼,為什麼要使用31這個數呢?其實上面的實現也可以總結成數數裡面下面這樣的公式 s 0 31 n 1 s 1 31 n 2 s n 1 原因如下 a.31是乙個素數,素數作用就是如果我用乙個數字來乘以這...

為什麼在定義hashcode時要使用31這個數呢?

public int hashcode hash h return h 該函式是我看的函式介面原始碼,為什麼要使用31這個數呢?其實上面的實現也可以總結成數數裡面下面這樣的公式 s 0 31 n 1 s 1 31 n 2 s n 1 原因如下 a.31是乙個素數,素數作用就是如果我用乙個數字來乘以這...