我几天前遇到了一个问题。现在我有数千万字,字符串类型。现在我决定将它们保存在数据库中并使用索引来保持它们的独特性。我不想比较原始单词以保持它们的独特性。我想确定一个字符串的hashCode()方法是否可以是唯一的,如果使用另一台笔记本电脑或不同的时间或类似的东西,它是否会被更改?
答案 0 :(得分:10)
独特,没有。从本质上讲,哈希值并不保证是唯一的。
任何具有任意数量可能输入和有限数量输出的系统都会发生冲突。
因此,如果哈希代码只基于 ,您将无法使用唯一数据库密钥来存储它们。但是,您可以使用非唯一键来存储它们。
回答第二个问题,即不同版本的Java是否会为同一个字符串生成不同的哈希码,没有。
如果Java实现遵循Oracle文档(否则它不是真正的Java实现),它将在所有实现中保持一致。 Oracle docs for String.hashCode
指定用于计算哈希值的固定公式:
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
如果你使用Java的疯狂不同的版本(例如1.2 vs 8),你可能想要检查一下这种情况,但是很长一段时间以来都是如此,至少从那以后1.5。
答案 1 :(得分:6)
下面是JVM所做的String的hashCode计算。如上所述,它纯粹基于单个字符及其在String中的位置进行计算,并且没有任何内容依赖于JVM或运行JVM的机器类型,这将改变哈希码。
这也是为什么String类被声明为final(不可扩展导致不变性)的原因之一,因此没有人改变它的行为。
以下是规格: -
public int hashCode()
返回此字符串的哈希码。 String对象的哈希码计算为
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
使用int算术,其中s[i]
是字符串的第i个字符,n是字符串的长度,^表示取幂。 (空字符串的哈希值为零。)
答案 2 :(得分:3)
没有
因为java中的字符串最多可以包含2,147,483,647(2 ^ 31 - 1)个字符,并且所有字符都会有所不同,所以它会产生非常大的组合,但整数只有-2,147,483,648到2,147,483,648的范围。所以这是不可能的,并且使用这种方法计算字符串的哈希码
s [0] * 31 ^(n-1)+ s [1] * 31 ^(n-2)+ ... + s [n-1]。
示例:
如果你创建了两个字符串变量" FB"和" Ea"哈希码将是相同的。