本文介绍了为什么Object.hashcode()在Java中有冲突?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在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中有冲突?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-30 14:04