问题描述
我在Windows XP的Hotspot JDK 1.6中运行以下代码,我运行了两次,结果如下.
I run the code below in Hotspot JDK 1.6 on Windows XP,I ran it twice and I got the results below.
因此,基本上object.hashcode()
似乎也有冲突?看起来好像没有在VM中返回内存地址.
So basically it seems the object.hashcode()
also have conflicts?it looks like it's not returning the memory address in the VM.
但是,JDK中的一条评论说这些值应该是不同的,任何人都可以解释吗?
However, a comment in the JDK said the values should be distinct, can anyone explain?
@return a hash code value for this object.
@see java.lang.Object#equals(java.lang.Object)
@see java.util.Hashtable
这是第一个结果:
i,hashcode(): 361,9578500
i,hashcode(): 1886,9578500
conflict:1886, 361
i,hashcode(): 1905,14850080
i,hashcode(): 2185,14850080
conflict:2185, 1905
9998
这是第二个结果:
i,hashcode(): 361,5462872
i,hashcode(): 1886,29705835
conflict:1887, 362
i,hashcode(): 1905,9949222
i,hashcode(): 2185,2081190
conflict:2186, 1906
9998
10000
我的代码:
@Test
public void testAddr()
{
Set<Integer> s = new TreeSet<Integer>();
Map<Integer, Integer> m = new TreeMap<Integer, Integer>();
Set<Object> os = new HashSet<Object>();
for(int i = 0; i < 10000; ++i)
{
Object o = new Object();
os.add(o);
Integer h = o.hashCode();
if((i == 361) || (i == 1886) || (i == 2185) || (i == 1905))
{
System.out.println("i,hashcode(): " + i + "," + h);
}
if(s.contains(h))
{
System.out.println("conflict:" + i + ", " + m.get(h));
}
else
{
s.add(h);
m.put(h, i);
}
}
System.out.println(s.size());
int c = 0;
for(Object o: os)
{
c++;
}
System.out.println(c);
}
推荐答案
hashCode()
应该用于在哈希表. hashCode
的规则不是不,尽管hashCode
永远不会产生冲突,尽管这是理想的属性,但是相等的对象必须具有相等的哈希码.这并不排除不相等的对象具有相等的哈希码.
hashCode()
is supposed to be used for placing objects in hash tables. The rule for hashCode
is not that hashCode
should never generate conflicts, although that is a desirable property, but that equal objects must have equal hash codes. This does not preclude non-equal objects from having equal hash codes.
您已经发现默认的Object.hashCode()
实现确实会为非相等对象生成相等的哈希码的情况.要求对象的哈希码不得更改,除非该对象与另一个对象的某些字段情感相等性发生更改.可能的原因是,垃圾收集器重新排列了内存,以使o
的后续实例与o
的早期实例位于同一位置(即,您在循环中分配了两个对象o
,并且垃圾收集器在两次分配之间重新安排了内存,以便将旧的o
从内存的一个位置移出,然后将新的o
分配到该位置.然后,即使旧的o
的哈希码无法更改,新的o
的哈希码还是新的o
在内存中存储的地址,该地址恰好等于该o
的哈希码.旧的o
.
You have found a case where the default Object.hashCode()
implementation does generate equal hash codes for non-equal objects. It is required that the hash code of an object not change unless there is a change to some field affection equality of that object with another. One possible cause is that the garbage collector rearranged memory so that a later instantiation of o
was at the same location as an earlier instantiation of o
(that is, you allocated two objects o
in the loop, and the garbage collector rearranged memory in between the two allocations so that the old o
was moved out of one location of memory and the new o
was then allocated at that location). Then, even though the hash code for the old o
cannot change, the hash code for the new o
is the address where the new o
is stored in memory, which happens to be equal to the hash code for the old o
.
这篇关于为什么Object.hashcode()在Java中有冲突?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!