国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JDK 是如何判斷兩個對象是否相同的?判斷的流程是什么?

JayChen / 1855人閱讀

JDK 是如何判斷兩個對象是否相同的呢?判斷的流程是什么?

參考解答:
JDK 會先判斷兩個對象的hashCode是否相同,如果hashCode不同,則說明肯定是兩個不同的對象了;如果hashCode相同再通過equals()方法進行進一步比較,如果equals方法返回true,則說明兩個對象是相同的,如果equals方法返回false說明兩個對象不同。

如何驗證

怎么來驗證這個問題呢?我們知道HashSet是不允許存儲相同的鍵值的。所以我們可以用HashSet存儲兩個相同的鍵值來模擬,看JDK是如何做判斷和識別的,從而驗證我們的猜想。

// 先自定義一個類并復寫 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的對象,代碼如下:

public class HashSetTest {
    public static void main(String[] args) {
      
        HashSet 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,則判斷為是重復的元素,就不往集合里添加了。

所以最終打印 HashSet 集合的時候可以看到,集合中只存放了一個元素。

注:所以平時我們在自定義一個類時,要謹慎把 equals 方法的返回值靜態的設置為 true,因為一旦產生哈希沖突,JDK 就會認為相同哈希值的對象就是同一個對象了。

我們再反證一下,把 equals 方法改為返回 false,模擬兩個hashCode相同,但是是兩個不同的對象的情景。

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

打印結果會如下:

判斷 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 去判斷兩個對象是否相同的。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/73383.html

相關文章

  • 一個有趣問題: 如何用HashSet來存儲重復字符串?

    摘要:注實際應用中,我們一般是用集合來存儲相同的字符串的,不會用來存。解答雖然我們不能用來存放類型重復的字符串,但我們可以用來存儲類型重復的字符串呀。而對于類型,相同字符串的不同對象哈希值是不同的。 有一種學得快的方法,就是不要一次學太多。 1. 前言 今天,我們來探討一個實際中不常用但卻比較有意思的問題。它能幫助你理解 HashSet中的鍵值是唯一的,不可重復的 這句話的真正含義,也考驗你...

    AprilJ 評論0 收藏0
  • 前百度面試官整理——Java后端面試題(一)

    摘要:發生了線程不安全情況。本來在中,發生哈希沖突是可以用鏈表法或者紅黑樹來解決的,但是在多線程中,可能就直接給覆蓋了。中,當同一個值上元素的鏈表節點數不小于時,將不再以單鏈表的形式存儲了,會被調整成一顆紅黑樹。 showImg(https://segmentfault.com/img/bVbsVLk?w=288&h=226); List 和 Set 的區別 List , Set 都是繼承自...

    JessYanCoding 評論0 收藏0
  • 加載機制

    摘要:如果沒有,那必須先執行相應的類加載過程。分配內存在類加載檢查通過后,接下來虛擬機將為新生對象分配內存。程序計數器主要有兩個作用字節碼解釋器通過改變程序計數器來依次讀取指令,從而實現代碼的流程控制,如順序執行選擇循環異常處理。 目錄介紹 01.Java對象的創建過程 1.0 看下創建類加載過程 1.1 對象的創建 1.2 對象的內存布局 02.Java內存區域 2.0 運行...

    mikyou 評論0 收藏0
  • JDK源碼閱讀(一):Object源碼分析

    摘要:最近經過某大佬的建議準備閱讀一下的源碼來提升一下自己所以開始寫源碼分析的文章閱讀版本為目錄結構圖構造器方法方法方法方法方法方法結構圖類構造器類構造器是創建對象的方法之一。還有一種情況是兩個元素不相同,但是相同,這就是哈希碰撞。 最近經過某大佬的建議準備閱讀一下JDK的源碼來提升一下自己 所以開始寫JDK源碼分析的文章 閱讀JDK版本為1.8 目錄 Object結構圖 構造器 eq...

    xuexiangjys 評論0 收藏0
  • Java String 源碼淺析

    摘要:如果對象長度不相等,則為假。從后往前,判斷類中數組的單個字符是否相等,有不相等則為假。由此可以看出,如果對兩個超長的字符串進行比較還是非常費時間的。字符串數值化比較將字符串數值化。 引言 從一段代碼說起: public void stringTest(){ String a = a+b+1; String b = ab1; System.out.println(...

    2shou 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<