hashCode唯一性 [英] hashCode uniqueness
问题描述
Object
的两个实例是否可以具有相同的hashCode()
?
Is it possible for two instances of Object
to have the same hashCode()
?
从理论上讲,对象的hashCode
是从其内存地址派生的,所以所有hashCodes
都应该是唯一的,但是如果对象在GC中移动,该怎么办?
In theory an object's hashCode
is derived from its memory address, so all hashCodes
should be unique, but what if objects are moved around during GC?
推荐答案
给出合理的对象集合,很可能会有两个具有相同的哈希码.在最好的情况下,它成为生日问题,与数以万计的对象发生冲突.在实践中,对象创建时使用的哈希码池相对较小,并且仅数千个对象就很容易发生冲突.
Given a reasonable collection of objects, having two with the same hash code is quite likely. In the best case it becomes the birthday problem, with a clash with tens of thousands of objects. In practice objects a created with a relatively small pool of likely hash codes, and clashes can easily happen with merely thousands of objects.
使用内存地址只是获取稍微随机数的一种方法. Sun JDK源有一个开关,可以使用安全随机数生成器或常数.我相信IBM(曾经使用过?)使用快速随机数生成器,但它一点也不安全.文档中提到的内存地址似乎具有历史性(大约十年前,具有固定位置的对象句柄并不罕见).
Using memory address is just a way of obtaining a slightly random number. The Sun JDK source has a switch to enable use of a Secure Random Number Generator or a constant. I believe IBM (used to?) use a fast random number generator, but it was not at all secure. The mention in the docs of memory address appears to be of a historical nature (around a decade ago it was not unusual to have object handles with fixed locations).
这是我几年前写的一些代码,用来展示冲突:
Here's some code I wrote a few years ago to demonstrate clashes:
class HashClash {
public static void main(String[] args) {
final Object obj = new Object();
final int target = obj.hashCode();
Object clash;
long ct = 0;
do {
clash = new Object();
++ct;
} while (clash.hashCode() != target && ct<10L*1000*1000*1000L);
if (clash.hashCode() == target) {
System.out.println(ct+": "+obj+" - "+clash);
} else {
System.out.println("No clashes found");
}
}
}
RFE来澄清文档,因为这太经常出现了: CR 6321873
RFE to clarify docs, because this comes up way too frequently: CR 6321873
这篇关于hashCode唯一性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!