8

java的hashCode()是确定性的吗?

我尝试实现一个使用 minhashing 算法的文档搜索引擎,并使用 hashCode 对单词进行预散列。每次我运行同一个词都会得到相同的哈希值吗?

即使我从不同的机器(32 位与 64 位)运行它,它是否会得到相同的哈希?

4

3 回答 3

11

这取决于您所指的课程。基本Object.hashCode实现不是,因为,如文档中所述

在合理可行的情况下,由 Object 类定义的 hashCode 方法确实为不同的对象返回不同的整数。(这通常通过将对象的内部地址转换为整数来实现,但 JavaTM 编程语言不需要这种实现技术。)

地址不是确定性的,考虑到有时它们甚至被用作熵的来源。

但是,例如,String具有如下确定的确定性哈希码:

来自维基百科的公式

(图片取自维基百科)

在某些情况下,哈希码甚至没有合理的确定性定义。

于 2013-05-08T16:02:44.840 回答
3

说到一般的对象:它没有。

但是,如果您专门谈论String,则哈希码计算在 API 中明确指定String.hashCode()

返回此字符串的哈希码。String 对象的哈希码计算为

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

使用 int 算术,其中 s[i] 是字符串的第 i 个字符,n 是字符串的长度,^ 表示求幂。(空字符串的哈希值为零。)

换句话说:您应该能够依赖 hashCode 对于字符串是稳定的。

于 2013-05-08T16:05:23.287 回答
3

hashCode 的一般合同如Javadoc所说:

每当在 Java 应用程序执行期间对同一个对象多次调用它时,hashCode 方法必须始终返回相同的整数,前提是没有修改对象上的 equals 比较中使用的信息。该整数不需要从应用程序的一次执行到同一应用程序的另一次执行保持一致。

每次我运行同一个词都会得到相同的哈希值吗?

在应用程序的执行过程中,调用hashCode()相同的词(我假设这个词是一个String实例并且equals()已经被覆盖String)应该返回相同的整数。

编辑由于javadoc指定String.hashCode()了如何计算字符串的哈希码,因此它是确定性的。

返回此字符串的哈希码。String 对象的哈希码是
计算为:
 s[0]*31^(n-1) + s 1 *31^(n-2) + ... + s[n-1]

于 2013-05-08T15:58:58.223 回答