最近出现了一个有趣的问题。我们遇到了一些使用hashCode()
作为MD5加密的salt源的代码但是这提出了一个问题:将hashCode()
返回不同VM,不同JDK版本和操作系统上相同对象的相同值?即使它没有保证,它现在在任何时候都有变化吗?
编辑:我的意思是String.hashCode()
,而不是更普遍的Object.hashCode()
,当然可以覆盖它。
答案 0 :(得分:8)
没有。来自http://tecfa.unige.ch/guides/java/langspec-1.0/javalang.doc1.html:
hashCode的一般契约是 如下:
- 每当在同一个对象上多次调用它时 执行Java应用程序, hashCode必须始终返回 相同的整数。整数可以是 正面,负面或零。这个 但是,整数不是必须的 从一个Java保持一致 申请到另一个,或从一个 执行应用程序到另一个 执行相同的应用程序。 [...]
答案 1 :(得分:3)
取决于类型:
来自.NET世界的一个警示故事:通过使用string.GetHashCode()的结果作为数据库中的密码哈希,我看到至少有一些人处于痛苦的世界。算法在.NET 1.1和2.0之间发生了变化,突然所有的哈希都是“错误的”。 (Jeffrey Richter通过C#记录了CLR中几乎完全相同的情况。)当需要存储哈希 时,我宁愿以总是的方式计算它>保证稳定 - 例如MD5或您的类型实现的自定义界面,保证稳定性。
答案 2 :(得分:2)
根据docs:String对象的哈希码计算为
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
我不确定这是正式规范还是Sun的实施。至少,它应该在所有现有的Sun VM上都是相同的,无论平台或操作系统如何。
答案 3 :(得分:1)
没有。除非另有说明,否则无法保证散列算法。因此,例如,哈希结构的反序列化需要重新计算哈希码,并且这些值不应以序列化形式存储。
答案 4 :(得分:0)
我想补充一点,您可以覆盖hashCode()(如果这样做,请不要忘记equals())以确保您的业务对象在任何地方返回相同的hashCode。那些对象至少会有一个可预测的hashCode。