2013-05-08 48 views
6

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

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

即使我从不同的机器上运行它(32位与64位),它会得到相同的散列吗?

+1

我不会赌那......甚至可能发生这样的事情:散列可能与对象的地址有关,然后它甚至可能从一次运行改变到下一次... – 2013-05-08 15:58:23

+0

请参阅http: //stackoverflow.com/questions/1516843/java-object-hashcode-result-constant-across-all-jvms-systems – Annabelle 2013-05-08 15:58:58

+0

为什么不让一个朋友运行一段代码示例并看看?为什么不发布这么小的代码,这样我们都可以做到这一点? :)这就是说,我不认为* hashCode在多次运行之间是一致的,只是为了保留在VM中。 – Shark 2013-05-08 15:59:23

回答

9

这取决于你所指的类。基地Object.hashCode执行不,因为,作为stated in the documentation

尽可能多是合理可行的,由Object类定义的hashCode方法不会返回针对不同的对象不同的整数。 (这一般是通过将所述物体的内部地址转换成一个整数实现,但不被的JavaTM编程语言不需要这种实现技巧。)

地址是不确定的,认为有时它们甚至用作熵的来源。

但是,例如,String已确定为确定性的哈希码如下:

Formula from Wikpedia

(图片来源于维基百科)

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

+0

+1,但您应该使用[javadoc](http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#hashCode%28%29)作为参考,而不是维基百科。 – assylias 2013-05-08 16:06:59

+2

我只说过公式图像是从维基百科复制的,而不是我用它作为参考。澄清。 – 2013-05-08 16:07:47

4

hashCode的一般合同是为Javadoc说:

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

Is the same word going to get the same hash every time that I run it?

的应用程序的执行过程中,在等于字(I假设词是String实例和equals()String被覆盖)调用hashCode()应返回相同的整数。

编辑由于javadocString.hashCode()指定字符串的哈希代码是如何计算的,它是确定的。

Returns a hash code for this string. The hash code for a String object is 
computed as : 
s[0]*31^(n-1) + s 1 *31^(n-2) + ... + s[n-1]

+4

你的答案很混乱。 'hashcode'对于Strings来说是明确定义的,无论机器是32位还是64位 – assylias 2013-05-08 16:07:58

+0

编辑!!!!!!!!!! – NINCOMPOOP 2013-05-08 16:11:09

+1

@assylias是的,这实际上可能是DoS风险!攻击者可以用一堆字符串(env vars和查询参数)构造一个HTTP请求,这个字符串被有意设计成具有相同的散列值,从而将一个〜O(1)散列映射有效地转换为一个O(N)链表。 Womp womp。 – yshavit 2013-05-08 16:12:34

3

说到一般物体:它没有。

但是如果你谈论specificially约String,则哈希码计算是明确的String.hashCode()在API中规定:

返回的哈希码此字符串。为字符串对象的哈希码被计算为使用INT算术,其中s [i]是字符串的第i个字符,n是串的长度

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

,和^表示幂。 (空字符串的哈希值是零。)

换句话说:你应该能够依靠哈希码是字符串稳定。