Java中的hashCode的計算方法與原理


前言

在Java中,每個對象都有一個從Object基類派生出的 hashCode() 方法,用於根據當前對象的某些特征返回一個整型變量。其核心源代碼(省略一些類型判斷與驗證代碼)如下所示:

public static int hashCode(byte[] value) {
    int h = 0;
    for (byte v : value) {
        h = 31 * h + (v & 0xff);
    }
    return h;
}

那么為什么要這么計算,31這個數字是哪來的,本文將從理論和實踐層面進行詳細說明。

計算公式

 

 

為什么是數字31?

由於哈希碼(HashCode)的目的是為了區分對象,所以其分布自然是越均勻越好。為了保證分布均勻,一般的方法是使用一些相對大的素質,但是為什么選擇了31,而不是 23、29、37 或者直接更大的,如97?

在 《Effective Java》48頁,第 3 章 “Always override hashcode when you override equals” 寫道[2]:

A nice property of 31 is that the multiplication can be replaced by a shift and a subtraction for better performance: 31 * i == (i << 5) - i. Modern VMs do this sort of optimization automatically.

 

也就是說 31 * i 可以用 (i << 5) - i 來計算,而移位操作的效率高於乘法,所以這是基於性能角度的考慮。所以31即滿足素數的要求,又可以快速計算,所以被使用在對極致性能要求的Java源代碼中。

結論

通過源代碼,我們可以看到Java對性能有極致的追求,就hashCode的實現代碼中,做了兩大優化:
1)使用加乘運行代替連續階乘運算以提高效率;
2)使用可以用位左移操作計算的31代替其他運算。

轉載:https://blog.csdn.net/weixin_43145361/article/details/105904810

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM