说一说java里面的hashcode–Object.hashcode()

http://www.hetaoblog.com/%E8%AF%B4%E4%B8%80%E8%AF%B4java%E9%87%8C%E9%9D%A2%E7%9A%84hashcode-object-hashcode/
java里面Object这个类的方法里面,一个重要的方法是hashcode(), 下面是javadoc
public int hashCode()
Returns a hash code value for the object. This method is supported for the benefit of hashtables such as those provided by java.util.Hashtable.
The general contract of hashCode is:

Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.
As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the JavaTM programming language.)

Returns:
a hash code value for this object.

这段话说了关于hashcode()这个函数的几个意思:
1. 用在Hashtable这个类, 其实其他还有HashMap, HashSet, ConcurrentHashMap等类上,一般类名里面有Hash字样的集合类,基本都要用到hashcode()这个函数
2. 同一个对象,如果用来在equals判断的属性未发生改变,那么在同一个进程里面hashcode()函数的多次调用,始终应该返回同一个整数
3. 如果两个对象用equals方法判断为相同,那么hashcode()也应该返回同样的值; 否则hashtable/hashmap这些类就不能正常工作了
4. 如果两个对象用equals方法判断为不同,hashcode可以一样, 就是所谓的hashcode()冲突; 虽然hashcode()可能冲突,但是冲突会使得hashtable()/hashmap()效率下降,我们在自己重写hashcode()函数的时候需要尽可能的让冲突减少; 事实上,很多情况下hashcode()的冲突是难以避免的;
5. jdk的javadoc说’As much as is reasonably practical’, Object.hashcode()会返回不同的值, 通常是返回对象的内存地址;
但是实际上,我在hotspot jdk 1.6.30/winxp下面测试,发现并没有返回对象的地址,并且的确是有冲突的,下面是测试代码和运行结果,


   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);
    }



我运行了两次,结果分别是
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

说明:
1. 代码最后的 for(Object o: os)里面对count统计出10000,表示所有对象都没有被回收,也就不可能存在同一个地址被两次分配空间的情况
2. 在这个10000的循环中,每次都有两组对象发生冲突,说明在这个版本的jdk里面,Object.hashcode()肯定没有返回对象的地址;
2. 在这个10000的循环中,每次都有两组对象发生冲突,说明在这个版本的jdk里

你可能感兴趣的:(hashCode())