關於Java中hashCode方法的實現源碼


首先來看一下String中hashCode方法的實現源碼。

public int hashCode() {
    int h = hash;
    if (h == 0 && value.length > 0) {
        char val[] = value;

       for (int i = 0; i < value.length; i++) {
            h = 31 * h + val[i];
        }
        hash = h;
    }
    return h;
}

在String中有一個私有實例字段hash表示該串的哈希值,在第一次調用hashCode方法時,字符串的哈希值被計算並且賦值給hash字段。之后再調用hashCode方法便可以直接取hash字段返回。

 

String類中的hashCode計算方法還是比較簡單的,就是一31為權,每一位字符的ASCII只進行計算,用自然溢出來等效取模。

哈希計算公式可以記為s[0]*31^(n-1)+s[1]*31^(n-2)+...+s[n-1]。

關於為什么取31為權,可以參考StackOverflow上的這個問題

主要原因是因為31是一個奇素數,所以31*i=32*i-i=(i<<5)-i,這種位移與剪發結合的計算相比一般的運算塊很多。

字符串哈希可以做很多事情,通常是類似於字符串判等,判回文之類的。

但是僅僅依賴於哈希值來判斷其實是不嚴謹的,除非能夠保證不會有哈希值沖突。通常這一點很難做到。

就拿jdk中String類的哈希方法來舉例,字符串“gdejicbegh”與字符串"hgebcijedg"具有相同的hashCode()返回值-801038016,並且他們具有reverse的關系。這個例子說明了用jdk中默認的hashCode方法判斷字符串相等或者字符串回文都存在反例。


免責聲明!

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



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