欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中==與equals()及hashcode()三者之間的關系詳解

 更新時間:2022年10月13日 09:29:37   作者:懶羊羊.java  
最近也是在讀Hollis的《深入理解Java核心技術》里面一節(jié)講到了equals()和hashcode()的關系,對于這個高頻面試點,咱們需要認真理清一下幾者之間的關系

1.= =

=為賦值運算符,==為比較運算符,僅比較對象的內存地址,無法比較真正意義上的相等!

JDK里的equals方法就是通過==來實現(xiàn)的比較對象的內存地址

以Integer為例

Integer a = 127;
Integer b = 127;
System.out.println(a == b);//true
Integer c = 128;
Integer d = 128;
System.out.println(c == d);//false

這里也是通過== 引出一個知識點,一個數(shù)值之差為啥導致結果不一樣?在[-128,127]的區(qū)間內Integer a = 127;由于設計了緩存,而后的Integer b = 127;就是直接利用的緩存里的數(shù)值對象,所以通過==比較的結果為true,因為他們本質還是一個數(shù)值對象

而Integer c = 128;Integer d = 128;就沒這樣幸運了,超過了緩存區(qū)間會重新new出對象,以至于兩者雖然數(shù)值相同但是地址不同

所以啊,==比較的是地址!也只是地址!

在前面==的基礎上,再來看equals()

2.equals()

以一個String類型的變量為例,當我們來使用equals()比較兩個對象時,結果肯定是false,因為equals()方法比較的是內存地址,這里的person1,person2均是兩次new出來的,所以地址肯定是不相同的,而person1,person3指向同一空間地址一定是相同的

Person person1 = new Person("lyy");
Person person2 = new Person("lyy");
Person person3 = person1;
System.out.println(person1.equals(person2));//false	
System.out.println(person1.equals(person3));//true

在不重寫的情況下,我們Ctrl+B看一下equals()的源碼:

public boolean equals(Object obj) {
    return (this == obj);
}

顯而易見的是 (this = = obj)是該方法的核心,而 = = 又是兩個對象比較的方式,= = 嘛比的是內存地址,懂的都懂噢

3.重寫equals()

記不記得你在刷面經或者短視頻的時候經常看到的一句話——比較兩個對象的內容是否相等時我們要重寫equals()方法!

這是為何?那我們不妨來重寫一下equals()試試水

@Override
public boolean equals(Object obj){
    if (this==obj){
        return true;
    }
    if (obj==null||getClass()!= obj.getClass()){
        return false;
    }
 Person person=(Person)obj;
    return Objects.equals(name,person.name);
}

重寫過equals后,原有的兩者就已發(fā)生翻天覆地的變化,從原來的比較內存地址——>比較對象內容,這是一件很神奇的事情,因為實現(xiàn)了比較不同對象的相同或者不同內容!

重寫之后:

具體是如何實現(xiàn)的呢?就像下面這樣…

4.equals()比較流程

下面我們來探索一下重寫的equals()是如何比較內容的:

通過debug來深入理解一下

下面來看一下debug過程中變量情況

總的來說,通過debug,重寫equals()來比較不同變量的不同或者相同內容得到了進一步論證!

5.hashcode()

我們在IDEA中通過CTRL+O的快捷鍵重寫hashcode()時它上面所屬的類是誰?

java.lang.Object!

顯而易見,該方法是Object類所定義的方法,作用是返回對象的哈希值返回值的類型為int(哈希值的作用是確定該對象在哈希表中的位置),曾經有這樣一句流川千古的話:你必須在每個重寫equals()的類中重寫一遍hashcode()方法

如果不這樣做將會違反Object.hashcode()的一般約定,這會阻止lei與所有基于散列的集合(比如hashmap,hashset…)一起正常工作。為啥?因為hashmap,hashset等基于散列的集合中,會使用對象的hashcode值來確定該對象應該如何存儲到集合中,并且再次使用hashcode來定位對象在集合中的位置

那么

在一個類中重寫了equals()但沒重寫hashcode()會出現(xiàn)啥情況呢?

我們來通過一個例子試試水~

嘗試把對象都放入一個不能重復的set里,然后看集合的長度來判斷兩個對象是否相等!

public class equals_hashcode {
    public static void main(String[] args) {
        Person person1 = new Person("lyy");
        Person person2 = new Person("lyy");
        HashSet<Person> set = new HashSet<>();
        set.add(person1);
        set.add(person2);
        System.out.println(set.size());
    }
}
class Person {
    public String name;
    public Person(String name) {
        this.name = name;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }
        Person person = (Person) obj;
        return Objects.equals(name, person.name);
    }
    @Override
    public int hashCode() {
        return Objects.hash(name);
    }
}

情況一:

當只重寫了equals()方法時運行的結果為2,由此得出兩個對象不相等!

情況二:

當既重寫了equals()和hashcode()后運行結果為1,所以兩個對象相等!

由此得出,對象相等的本質是:

1.地址相同

2.哈希值相同(重寫hashcode的體現(xiàn))

這也不難聯(lián)系到之前的約定了,在比較對象是否相等的場景下,我們必須重寫equals()和hashcode()!

對象相等建立在==之上,equals(),hashcode()的雙重寫是對象相等的基本準則!

到此這篇關于Java中==與equals()及hashcode()三者之間的關系詳解的文章就介紹到這了,更多相關Java == equals() hashcode()內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • SpringBoot實現(xiàn)定時發(fā)送郵件的三種方法案例詳解

    SpringBoot實現(xiàn)定時發(fā)送郵件的三種方法案例詳解

    這篇文章主要介紹了SpringBoot三種方法實現(xiàn)定時發(fā)送郵件的案例,Spring框架的定時任務調度功能支持配置和注解兩種方式Spring?Boot在Spring框架的基礎上實現(xiàn)了繼承,并對其中基于注解方式的定時任務實現(xiàn)了非常好的支持,本文給大家詳細講解,需要的朋友可以參考下
    2023-03-03
  • 在Android的應用中實現(xiàn)網絡圖片異步加載的方法

    在Android的應用中實現(xiàn)網絡圖片異步加載的方法

    這篇文章主要介紹了在Android的應用中實現(xiàn)網絡圖片異步加載的方法,一定程度上有助于提高安卓程序的使用體驗,需要的朋友可以參考下
    2015-07-07
  • Java多線程基礎 線程的等待與喚醒(wait、notify、notifyAll)

    Java多線程基礎 線程的等待與喚醒(wait、notify、notifyAll)

    這篇文章主要介紹了Java多線程基礎 線程的等待與喚醒,需要的朋友可以參考下
    2017-05-05
  • Java使用ExecutorService來停止線程服務

    Java使用ExecutorService來停止線程服務

    這篇文章主要介紹了Java使用ExecutorService來停止線程服務,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-04-04
  • Java操作Mysql的方法

    Java操作Mysql的方法

    這篇文章主要介紹了Java操作Mysql的方法,實例分析了Java針對有返回結果和沒有返回結果的sql操作的相關技巧,需要的朋友可以參考下
    2015-02-02
  • 一文詳解如何使用線程池來優(yōu)化我們的應用程序

    一文詳解如何使用線程池來優(yōu)化我們的應用程序

    線程池是一種工具,但并不是適用于所有場景。在使用線程池時,我們需要根據(jù)應用程序的性質、計算資源的可用性和應用程序的需求進行適當?shù)呐渲谩1疚闹饕榻B了如何使用線程池來優(yōu)化我們的應用程序,需要的可以參考一下
    2023-04-04
  • ruoyi微服務版本搭建運行方式

    ruoyi微服務版本搭建運行方式

    這篇文章主要介紹了ruoyi微服務版本搭建運行方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • springBoot中的properties配置解析

    springBoot中的properties配置解析

    這篇文章主要介紹了springBoot中的properties配置解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • SpringAOP事務配置語法及實現(xiàn)過程詳解

    SpringAOP事務配置語法及實現(xiàn)過程詳解

    這篇文章主要介紹了SpringAOP事務配置語法及實現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-06-06
  • Java實現(xiàn)Socket的TCP傳輸實例

    Java實現(xiàn)Socket的TCP傳輸實例

    這篇文章主要介紹了Java實現(xiàn)Socket的TCP傳輸,實例分析了java通過socket實現(xiàn)TCP傳輸?shù)南嚓P技巧,需要的朋友可以參考下
    2015-05-05

最新評論