JDK 是如何判斷兩個對象是否相同的呢?判斷的流程是什麼?java
參考解答: JDK 會先判斷兩個對象的hashCode是否相同,若是hashCode不一樣,則說明確定是兩個不一樣的對象了;若是hashCode相同再經過equals()方法進行進一步比較,若是equals方法返回true,則說明兩個對象是相同的,若是equals方法返回false說明兩個對象不一樣。ide
怎麼來驗證這個問題呢?咱們知道HashSet是不容許存儲相同的鍵值的。因此咱們能夠用HashSet存儲兩個相同的鍵值來模擬,看JDK是如何作判斷和識別的,從而驗證咱們的猜測。spa
// 先自定義一個類並複寫 hashCode 和 equals 方法
public class CustomClass {
@Override
public int hashCode() {
System.out.println("判斷 hashCode");
return 1; // 返回1,說明全部新建的對象的哈希值都爲1,也就是相同
}
@Override
public boolean equals(Object o) {
System.out.println("判斷 equals");
return true; // 返回true
}
}
複製代碼
接下來咱們用HashSet來存儲兩個自定義的CustomClass的對象,代碼以下:code
public class HashSetTest {
public static void main(String[] args) {
HashSet<CustomClass> hs = new HashSet<>();
CustomClass cs1 = new CustomClass();
CustomClass cs2 = new CustomClass();
hs.add(cs1);
hs.add(cs2);
System.out.println("----hs添加完畢");
System.out.println("hs:"+hs); // 打印一下hashSet集合看裏面存放了什麼
}
}
複製代碼
打印結果以下:對象
判斷 hashCode
判斷 hashCode
判斷 equals
----hs添加完畢
判斷 hashCode // 此處的判斷是打印輸出語句執行時調用的,與分析本問題無關
hs:[com.alankeene.javalib.collections.CustomClass@1]
複製代碼
結果分析: 執行 hs.add(cs1)
語句的時候,JDK 會先判斷 cs1 所指向對象的hashCode,由於是第一次往HashSet集合裏面存放元素,該元素 hashCode 在集合中確定是還沒存在的,這是個新的元素,因此直接存放進集合中,不用調用 cs1 所指向對象的 equals 方法。 當執行 hs.add(cs2)
語句時,這是第二次往集合裏存放元素,有新的元素 cs2 要添加進來,那先要調用 cs2 所指向對象的 hashCode 方法看看它的哈希值是否是與集合中已有元素的哈希值重複了,發現重複了,哈希值都是1,那有多是同一個對象,那就要調用 cs2 所指向對象的 equals 方法作進一步判斷,發現 equals 方法返回 true,則判斷爲是重複的元素,就不往集合裏添加了。string
因此最終打印 HashSet 集合的時候能夠看到,集合中只存放了一個元素。hash
注:因此平時咱們在自定義一個類時,要謹慎把 equals 方法的返回值靜態的設置爲 true,由於一旦產生哈希衝突,JDK 就會認爲相同哈希值的對象就是同一個對象了。it
咱們再反證一下,把 equals 方法改成返回 false,模擬兩個hashCode相同,可是是兩個不一樣的對象的情景。io
public class CustomClass {
@Override
public int hashCode() {
System.out.println("判斷 hashCode");
return 1; // 返回1,說明全部新建的對象的哈希值都爲1,也就是相同
}
@Override
public boolean equals(Object o) {
System.out.println("判斷 equals");
return false; // 返回false
}
}
複製代碼
打印結果會以下:function
判斷 hashCode
判斷 hashCode
判斷 equals
----hs添加完畢
判斷 hashCode // 此處的判斷是打印輸出語句執行時調用的,與分析本問題無關
判斷 hashCode // 此處的判斷是打印輸出語句執行時調用的,與分析本問題無關
hs:[com.alankeene.javalib.collections.CustomClass@1, com.alankeene.javalib.collections.CustomClass@1]
複製代碼
會發現,HashSet集合中存放了兩個元素了,說明雖然 cs1 和 cs2 的哈希值相同,可是 JDK 判斷爲不一樣的元素並存入集合中了。
由此,驗證了咱們的猜測。JDK 是先判斷 hashCode,若是 hashCode 相同再經過 equals 去判斷兩個對象是否相同的。