您好,登錄后才能下訂單哦!
這篇文章主要介紹“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
比較的是他們的值是否相等,比如兩個int類型的變量,比較的是變量的值是否一樣。
比較的是引用的地址是否相同,比如說新建了兩個User對象,比較的是兩個User的地址是否一樣。
基本類型的包裝類 也算是對象,不管是否使用常量池,只要一方通過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
以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
賦值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; }
我們通常使用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
在大多數Java類庫中的類中 如基本類型中封裝類Integer和String的equalse方法都是被重寫過的,所以比較的是值
通常我們使用equalse都是自己覆寫方法來對比對象內部的屬性值是否相同
結論:hashcode相同,值不一定相同,值相同hashCode一定相同(重寫hashCode方法)
hashCode是所有java對象的固有方法,如果不重寫的話,返回的實際上是該對象在jvm的堆上的內存地址,而不同對象的內存地址肯定不同,所以這個hashCode也就肯定不同了。如果重寫了的話,由于采用的算法的問題,有可能導致兩個不同對象的hashCode相同。
hashCode和equals兩個方法是有語義關聯的,它們需要滿足:
A.equals(B)==true --> A.hashCode()==B.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一定相同
到此,關于“java==和equalse的區別是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。