下圖是規范中要求的:

圖解:比如equals相等的箭頭指向hashcode相等,標示equals相等那么必有hashcode相等。另外有兩個箭頭指向別人的標示可能是其中之一。
//JAVA代碼: public static void main(String[] args) { Object obj1 = new Object(); Object obj2 = new Object(); Object obj3 = obj2; System.out.println("obj1 equals obj2 ?" + obj1.equals(obj2)); System.out.println("obj2 equals obj3 ?" + obj2.equals(obj3)); System.out.println("obj1's hashcode: " + obj1.hashCode()); System.out.println("obj2's hashcode: " + obj2.hashCode()); System.out.println("obj2's hashcode: " + obj3.hashCode()); } } //輸出結果: obj1==obj2 ?false obj2==obj3 ?true obj1's hashcode: 12677476 obj2's hashcode: 33263331 obj3's hashcode: 33263331
也就是當我們寫了一個自己的class,然后用class new了兩個對象,如果在這兩個對象上用equals時,此時比較的兩個引用是不是一樣,也就是他們的物理地址是不是一樣,如果不一樣的話,就會返回false. 我們實際用的時候,往往不是希望比較兩個對象的物理地址是不是一樣,而比較兩個對象的屬性等東西是不是一樣,所以Object提供的方法往往不能滿足我們要求。 這就需要我們覆蓋Object的equals方法。
如果要覆蓋Object的equals的方法,一定要滿足以下幾個等價關系:
1. 自反性,對於任何非null的引用值x,x.equals(x)必須反回true
2. 對稱性,對於任何非null的引用值x,y,當且僅當y.equals(x)返回true時,x.equals(y),才返回true.
3. 傳遞性,對於任何非null的引用值x,y,z,如果x.equals(y)返回true,並且y.equals(z)返回ture,那 么x.equals(z)也必須返回true.
4. 一致性,對於任何非null的引用值x,y,只要equals比較操作的兩個對象中所用的信息沒有被修改,多次 調用x.equals(y)就會一致的返回true,或者一致的返回false.
5.對於任何的非null的值x,x.equals(null),必須返回false .
如果我們的程序中沒有完全遵守這些約定,那么你的程式就有可能發生問題。
沒有出問題的原因是,因為你的程序沒有地方 直接調用 或者 間接調用 equals方法。 什么是直接調用equals ,什么是間接調用equals呢? 直接調用equals方法就是說,你顯式的在你的程序中對你自己的寫的對象上面調用equals方法, 間接調用呢,用一簡單的例子來說,當我們平常會把一個些對象放到collection,為了不重復,我們有調用collection的contains方法,此時就間接調用了collection中對象的equals方法。
覆蓋了equals的類中,也必須覆蓋hashCode方法
簡單的結論:當對象類沒有不符合規范的override equals()和hashcode()方法的時候,兩個對象做比較
- 如果equals()比較相同,那么hashcode()肯定相同。
- 如果hashcode()比較相同,那么equals()不一定相同。
眾所周之,String 、Math、還有Integer、Double。。。。等這些封裝類重寫了Object中的equals()方法,讓它不再比較句柄(引用),而是比較對象中實際包含的整數的值,即比較的是內容。
而Object的equals()方法比較的是地址值。 一般來說,如果你要把一個類的對象放入容器中,那么通常要為其重寫equals()方法,讓他們比較地址值而不是內容值。特別地,如果要把你的類的對象放入散列中,那么還要重寫hashCode()方法;要放到有序容器中,還要重寫compareTo()方法。
為什么要重寫hashCode方法? 我們應該先了解java判斷兩個對象是否相等的規則。 在java的集合中,判斷兩個對象是否相等的規則是:
首先,判斷兩個對象的hashCode是否相等 如果不相等,認為兩個對象也不相等 如果相等,則判斷兩個對象用equals運算是否相等 如果不相等,認為兩個對象也不相等 如果相等,認為兩個對象相等
我們在equals方法中需要向下轉型,效率很低,所以先判斷hashCode方法可以提高效率。
equals()相等的兩個對象,hashcode()一定相等; equals()不相等的兩個對象,卻並不能證明他們的hashcode()不相等。換句話說,equals()方法不相等的兩個對象,hashcode()有可能相等。(我的理解是由於哈希碼在生成的時候產生沖突造成的)。
反 過來:hashcode()不等,一定能推出equals()也不等;hashcode()相等,equals()可能相等,也可能不等。
