中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java==和equalse的區別是什么

發布時間:2021-11-24 15:25:12 來源:億速云 閱讀:147 作者:iii 欄目:大數據

這篇文章主要介紹“java==和equalse的區別是什么”,在日常操作中,相信很多人在java==和equalse的區別是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”java==和equalse的區別是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

1.總的來說==和equalse 比較的都是地址值;

2.==在對比基本數據類型和包裝類的常量池的時候,比較的是值

3.equalse是方法,只能作用于對象數據(Integer等封裝類也是對象哈),默認也是比較地址值,但是大多數情況下我們是覆寫equalse方法來對比其屬性值是否一樣;

4.但是equalse方法可以被重寫。基本類型中封裝類Integer和String的equalse方法都是被重寫過的,所以比較的是值

5.Integer的常量池很好理解 -128   127,String也有常量池,我們字面創建String a=“xxx”這種都是進入常量池

    String的常量池說明可以參考這篇文章: https://www.cnblogs.com/tongkey/p/8587060.html

分開講述==和equalse

一、先說==,在比較不同數據的時候效果

1. 基礎數據類型:

        比較的是他們的值是否相等,比如兩個int類型的變量,比較的是變量的值是否一樣。

2. 引用數據類型:

        比較的是引用的地址是否相同,比如說新建了兩個User對象,比較的是兩個User的地址是否一樣。

3.基本類型的包裝類問題

    3.1包裝類,通過new創建對象

        基本類型的包裝類 也算是對象,不管是否使用常量池,只要一方通過new創建對象,那就一定是比較的地址值

    以Integer舉例

不使用常量池:-128  127 
 public static void equalsTest(){
    Integer A=new Integer(1);
    Integer B=new Integer(1);;
    if(A==B){
      System.out.println("A=B");
    }else{
      System.out.println("A!=B");
    }
  }

輸出結果為:A!=B

使用常量池
  public static void equalsTest(){
    Integer A=new Integer(128);
    Integer B=new Integer(128);;
    if(A==B){
      System.out.println("A=B");
    }else{
      System.out.println("A!=B");
    }
  }

輸出結果為:A!=B

        

    3.2基本類型的包裝類 不使用new創建對象的時候

       以Integer舉例

     在-128  127的時候,會使用常量池數據,從而比較對象值;不使用常量池的時候,會比較地址值

 使用常量池的時候-128  127
  public static void equalsTest(){
    Integer A=-127;
    Integer B=-127;;
    if(A==B){
      System.out.println("A=B");
    }else{
      System.out.println("A!=B");
    }
  }
輸出結果為:A=B

不使用常量池的時候,比較的是地址值

 public static void equalsTest(){
    Integer A=128;
    Integer B=128;;
    if(A==B){
      System.out.println("A=B");
    }else{
      System.out.println("A!=B");
    }
  }
輸出結果為:A!=B

    3.3Integer的特殊情況 Integer在用==對比int類型的時候,無論何時都是對比的值

賦值128,沒有使用到常量池  

public static void equalsTest(){
    Integer A=new Integer(128);
    int B=128;
    if(A==B){
      System.out.println("A=B");
    }else{
      System.out.println("A!=B");
    }
  }
輸出結果為:A=B
查看源碼 發現 Integer只會對int作值的比較

/**
     * Compares this object to the specified object.  The result is
     * {@code true} if and only if the argument is not
     * {@code null} and is an {@code Integer} object that
     * contains the same {@code int} value as this object.
     *
     * @param   obj   the object to compare with.
     * @return  {@code true} if the objects are the same;
     *          {@code false} otherwise.
     */
    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

    3.4 String類型的使用常量池對比的也是值(絕大多數情況都是用到常量池)

      我們通常使用String A="hello";這種方式創建的所有變量所有的都進了字符串常量池

  這種創建方式都是會使用到常量池
public static void equalsTest(){
    String A="hello";
    String B="hello";
    if(A==B){
      System.out.println("A=B");
    }else{
      System.out.println("A!=B");
    }
  }
輸出結果為: A=B

我們通常使用String A="hello";這種方式創建的所有變量所有的都進了字符串常量池

String類的final修飾的,以字面量的形式創建String變量時,jvm會在編譯期間就把該字面量(“hello”)放到字符串常量池中,由Java程序啟動的時候就已經加載到內存中了。這個字符串常量池的特點就是有且只有一份相同的字面量,如果有其它相同的字面量,jvm則返回這個字面量的引用,如果沒有相同的字面量,則在字符串常量池創建這個字面量并返回它的引用

                3.5  String類型不使用常量池的情況,比較的是地址值

  public static void equalsTest(){
    String A="hello";
    String B=new String("hello");;
    if(A==B){
      System.out.println("A=B");
    }else{
      System.out.println("A!=B");
    }
  }
輸出結果為:A!=B
通過new創建對象,使用的是新的對象,結果自然不相等


  public static void equalsTest(){
    String A="hello";
    String B=new String("hello");
    //B引用變為常量池的hello的引用
    B=B.intern();
    if(A==B){
      System.out.println("A=B");
    }else{
      System.out.println("A!=B");
    }
  }
輸出結果為:A=B

二、equalse是方法,只能作用于對象數據(Integer等封裝類也是對象哈),默認也是比較地址值

        1.equalse方法默認還是比較地址值。但是可以被重寫

                在大多數Java類庫中的類中 如基本類型中封裝類Integer和String的equalse方法都是被重寫過的,所以比較的是值

                通常我們使用equalse都是自己覆寫方法來對比對象內部的屬性值是否相同

三、值相同的時候,hashcode不一定相同

    結論:hashcode相同,值不一定相同,值相同hashCode一定相同(重寫hashCode方法)

                

    1. 為什么ashcode相同,值一定相同,值相同hashCode不一定相同

                hashCode是所有java對象的固有方法,如果不重寫的話,返回的實際上是該對象在jvm的堆上的內存地址,而不同對象的內存地址肯定不同,所以這個hashCode也就肯定不同了。如果重寫了的話,由于采用的算法的問題,有可能導致兩個不同對象的hashCode相同。

    2.hashCode和equalse的關聯關系

                    hashCode和equals兩個方法是有語義關聯的,它們需要滿足:

                    A.equals(B)==true --> A.hashCode()==B.hashCode()

                    因此重寫其中一個方法時也需要將另一個也重寫。

    3.HashCode方法重寫需要滿足規范

             如果根據 equals(Object) 方法,兩個對象是相等的,那么對這兩個對象中的每個對象調用 hashCode 方法都必須生成相同的整數結果。

         3.1 hashCode的重寫實現需要滿足不變性,即一個object的hashCode不能前一會是1,過一會就變成2了。

         3.2 hashCode的重寫實現最好依賴于對象中的final屬性,從而在對象初始化構造后就不再變化。一方面是jvm便于代碼優化,可以緩存這個hashCode;另一方面,在使用hashMap或hashSet的場景中,如果使用的key的hashCode會變化,將會導致bug,比如放進去時key.hashCode()=1,等到要取出來時key.hashCode()=2了,就會取不出來原先的數據。

    4.hashCode為什么會存在相同的情況

        以hashSet舉例,hashSet JDK1.8以前底層結構是數組+鏈表的形式,1.8之后是數組+鏈表+紅黑樹

           以1.8舉例:

         在向hashSet集合中添加元素時,需要經過兩個步驟

  • 計算hashcode并與hashSet數組中的hashcode進行比較

  • 如果有相同的hashcode,則對該hash的內容使用equals進行比較,如果不同則存入集合

         因此相同的hashcode不一定有相同的值,但是如果值相同,那他的hashcode一定相同  

   4. 只要使用HashSet存儲自定義類型的數據切記要重寫equals和hashCode方法

到此,關于“java==和equalse的區別是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

射阳县| 虎林市| 土默特左旗| 昌图县| 广水市| 马龙县| 仁寿县| 宣恩县| 西峡县| 股票| 碌曲县| 高邮市| 浦东新区| 法库县| 华阴市| 安吉县| 渭源县| 奈曼旗| 安乡县| 元江| 达州市| 科技| 郎溪县| 平顶山市| 洱源县| 安国市| 信丰县| 石渠县| 阆中市| 宁南县| 广水市| 汉寿县| 当涂县| 洞头县| 侯马市| 扎囊县| 利川市| 通道| 德阳市| 齐齐哈尔市| 三门县|