2013-03-28 49 views
5

我已經在.NET中請求similar question瞭解string.GetHashCode()方法。從那時起,我已經瞭解到,如果我們要在不同的機器上使用哈希代碼,我們不能依賴隱式實現哈希代碼。因此,我假設String.hashCode()的Java實現在不同的硬件配置下也不穩定,並且可能在不同的虛擬機之間表現不同(不要忘記不同的虛擬機實現)羣集中的計算機之間的Java和string.hashCode()穩定性

目前我們正在討論一種安全地將字符串轉換爲通過哈希計算,但散列算法必須在羣集的不同節點上保持穩定,並且要快速評估,因爲使用頻率很高。我的隊友堅持使用原生方法,我需要一些合理的論據讓他們重新考慮另一種方法。目前,我只能想到機器配置(x86和x64)與可能不同的某些機器上JVM的供應商(我們的情況幾乎不適用)和字節順序差異(取決於算法所在的機器)之間的差異跑。當然,字符編碼也可能被考慮。儘管所有這些東西都出現在我的腦海中,但我不能100%肯定他們兩個都有足夠的理由,我很感謝你在這方面的專業知識和經驗。這將幫助我建立更有力的論據來支持編寫自定義哈希算法。此外,我很感謝什麼不執行實施它時。

+1

字符串散列碼在任何Java平臺上定義良好且相同。 – ZhongYu

+1

http://stackoverflow.com/questions/785091/consistency-of-hashcode-on-a-java-string – zch

+0

@ zhong.j.yu你假設[JRockit](http://www.oracle.com /technetwork/middleware/jrockit/overview/index.html)和[IBM JVM](http://publib.boulder.ibm。com/infocenter/java7sdk/v7r0/index.jsp?topic =%2Fcom.ibm.java.lnx.70.doc%2Fuser%2Fjava_jvm.html)對'String#hashCode'具有相同的實現。 –

回答

11

String.hashCode()實施是文檔中specified,所以它的保證是一致的:

在字符串對象的哈希碼被使用INT算術,其中s計算爲

s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1] 

[i]是字符串的第i個字符,n是字符串的長度,^表示取冪。 (空字符串的散列值爲零)

所有這些操作都是針對Java平臺獨立實現的 - 例如,平臺字節順序無關緊要。

也就是說,得到 a String的方法可能會很棘手,如果你從文件或其他字節來源獲得它。在這種情況下,只要您明確指定Charset即可。 (請記住,String都不具備的不同編碼本身;編碼是轉換一個byte[]String之間的規範。)

+0

就規格說明而言(以及我知道的核心Java組件),它實際上似乎足夠安全。謝謝 –

3

你可以看看sourcecode, also shown below。從我所能看到的(經過10秒鐘的分析)之後,這應該在機器和架構中保持穩定。路易斯通過引用一個規範來證實這一點,如果你相信規格,那就更好了。 :-)

但是,如果不同的JRE選擇以不同的方式實施並違反規範,則可能會有所不同。

public int hashCode() { 
    int h = hash; 
    if (h == 0) { 
     int off = offset; 
     char val[] = value; 
     int len = count; 

     for (int i = 0; i < len; i++) { 
      h = 31*h + val[off++]; 
     } 

     hash = h; 
    } 

    return h; 
} 
+0

謝謝你的回答。我自己查看了源代碼,但沒有發現任何可能成爲問題的內容。不過,有些東西告訴我,這不是唯一可能出錯的地方。希望同一集羣中的不同JVM(不同的供應商)不會成爲我們的案例。 –

+1

我認爲,如果一個供應商違反規範,你可以運行一串已知的字符串,並與官方結果進行比較。一定要運行一些_long_。早在Java早期,hashCode方法只考慮了前16個(也許是32個)字符。我可以看到一家供應商試圖通過類似的方式贏得基準。 – user949300

+0

很好的建議,謝謝分享。我相信對於目前的事情,我們會堅持使用甲骨文的JVM,儘管這種知識有一天可能會非常有用。有這樣的想法,這種「性能增益」可能會耗費大量不受歡迎的和不可預知的行爲。不知道那裏的JVM供應商是否屬於這個類別 –