偶爾看到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; }
以31為權,每一位為字符的ASCII值進行運算,用自然溢出來等效取模。 ASCII碼見 http://blog.csdn.net/lucky_bo/article/details/52247939
哈希計算公式可以計為s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
用31做基礎 ,主要是因為31是一個奇質數,所以31*i=32*i-i=(i<<5)-i,這種位移與減法結合的計算相比一般的運算快很多。 參考stackworkflow ,
hashmap的hashcode也是如此
注意上面代碼有兩個問題:
1.hash碼采用int 保存 可能會又重復
System.out.println("ABCDEa123abc".hashCode()); // 165374702
System.out.println("ABCDFB123abc".hashCode()); // 165374702
2.對入具有reverse關系的字符串 會返回相同的hashcode 如: 字符串"gdejicbegh"與字符串"hgebcijedg"具有相同的hashCode()返回值-801038016
這里擴展一下 關於字符串的reverse方法 jdk中提供Stringbuffer的reverse方法 采用unicode代理解決 參考此鏈接 http://www.importnew.com/501.html