關於Java中String類的hashCode方法


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

 1 public int hashCode() {  2     int h = hash;  3     if (h == 0 && value.length > 0) {  4         char val[] = value;  5 
 6         for (int i = 0; i < value.length; i++) {  7             h = 31 * h + val[i];  8  }  9         hash = h; 10  } 11     return h; 12 }

在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