对于不同类型的对象,hashCode()方法计算hashcode值的公式不一样,它们都是重写的Object的hashCode()方法。
对于两个对象,
如果调用equals方法得到的结果为true,则两个对象的hashcode值必定相等;(1)
如果equals方法得到的结果为false,则两个对象的hashcode值不一定不同; (2)
如果两个对象的hashcode值不等,则equals方法得到的结果必定为false; (3)
如果两个对象的hashcode值相等,则equals方法得到的结果未知。 (4)
暂时这样理解:
hashcode的值是由对象内容等决定的。但是因为计算方法不同等原因不同的对象内容可能产生一样的hashcode值。
(1) 对于对象来说,equals方法比较的是对象内容,如果两个对象可以用equals来比较且比较结果为true,那么这两个对象计算hashcode的方法一样,且对象内容一样,所以hashcode值肯定相等。
(2) equals得到的结果为false说明两个对象的内容不同,但是对象内容不同计算出来的hashcode值有可能相等,不一定不同。
(3) 由(1) 可知,两对象equals方法结果为true的话,hashcode值肯定相等。那么反过来,如果hashcode值不相等,则equals方法结果必定false。用反证法易知。
(4) 如果前三条弄明白了。那么第四条显而易见。
对于java中的比较而言:
基本数据类型比较用“==”,他们没有equals方法。
对于复合数据类型,当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。 JAVA当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个equals的方法,这个方法的初始行为是比较对象的内存地 址,但在一些类库当中这个方法被覆盖掉了,而不再是比较类在堆内存中的存放地址了。如String,Integer,Date在这些类当中equals有其自身的实现,对于复合数据类型之间进行equals比较,在没有覆写equals方法的情况下,他们之间的比较还是基于他们在内存中的存放位置的地址值的,因为Object的equals方法也是用双等号(==)进行比较的,所以比较后的结果跟双等号(==)的结果相同。
下面这段话摘自Effective Java一书:
- 在程序执行期间,只要equals方法的比较操作用到的信息没有被修改,那么对这同一个对象调用多次,hashCode方法必须始终如一地返回同一个整数。
- 如果两个对象根据equals方法比较是相等的,那么调用两个对象的hashCode方法必须返回相同的整数结果。
- 如果两个对象根据equals方法比较是不等的,则hashCode方法不一定得返回不同的整数。