2013-03-28 29 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供应商是否属于这个类别 –