您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關String類型等值比較引起的“==”、“equals()”和“hashCode”詳解,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
String類型的等值比較和內容比較
字符串等值比較
public final class String implements java.io.Serializable, Comparable<String>, CharSequence { /** The value is used for character storage. */ private final char value[]; public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }
首先,如上述String的源碼可以知道的是,java中等值比較,就是“==”比較,比較的是地址。字符串本質上是final修飾的字符數組,也就是說,當創建字符串對象時,字符串的引用是常量,但它每一個對象的值可以改變。
字符串內容比較
如上述String的源碼可以知道的是,字符串的內容比較就是所謂的字符串的equals()方法,比較的是兩個字符串對象儲存的值,也就是內容是否相等,所謂內容相同,就是字符串每一個位置的字符相同。這里值得注意的是String重寫了Object的equals()方法(Object的==與equals()是一樣的)
地址分配圖示
很明顯str1和str2的地址相同,他們與str3的地址不相同,但是str3通過方法intern(),可以強制入池,和str1和str2的地址相同。
結論
字符串:默認為常量------------進常量池
String val = “xxx”;---------------------------默認入池
String val = new String(“xxx”);--------------------------默認入堆,但可以通過intern()強制入池(堆里的對象還在)
上面只是簡單的介紹string類的對象等值比較,下面我們來深刻的了解下java 對象的等值判斷。
對象相等判斷
== 和 equals 的區別是什么
== : 它的作用是判斷兩個對象的地址是不是相等。即,判斷兩個對象是不是同一個對象。(基本數據類型 == 比較的是值,引用數據類型 == 比較的是內存地址)
equals() : 它的作用也是判斷兩個對象是否相等。但它一般有兩種使用情況:
情況1:類沒有覆蓋 equals() 方法。則通過 equals() 比較該類的兩個對象時,等價于通過“==”比較這兩個對象。
情況2:類覆蓋了 equals() 方法。一般,我們都覆蓋 equals() 方法來兩個對象的內容相等;若它們的內容相等,則返回 true (即,認為這兩個對象相等)。
舉個例子:
public class test1 { public static void main(String[] args) { String a = new String("ab"); // a 為一個引用 String b = new String("ab"); // b為另一個引用,對象的內容一樣 String aa = "ab"; // 放在常量池中 String bb = "ab"; // 從常量池中查找 if (aa == bb) // true System.out.println("aa==bb"); if (a == b) // false,非同一對象 System.out.println("a==b"); if (a.equals(b)) // true System.out.println("aEQb"); if (42 == 42.0) { // true System.out.println("true"); } } }
說明:
String中的equals方法是被重寫過的,因為object的equals方法是比較的對象的內存地址,而String的equals方法比較的是對象的值。
當創建String類型的對象時,虛擬機會在常量池中查找有沒有已經存在的值和要創建的值相同的對象,如果有就把它賦給當前引用。如果沒有就在常量池中重新創建一個String對象。
hashCode 與 equals (重要)
HashSet如何檢查重復
兩個對象的 hashCode() 相同,則 equals() 也一定為 true,對嗎?
hashCode和equals方法的關系
面試官可能會問你:“你重寫過 hashcode 和 equals 么,為什么重寫equals時必須重寫hashCode方法?”
hashCode()介紹
hashCode() 的作用是獲取哈希碼,也稱為散列碼;它實際上是返回一個int整數。這個哈希碼的作用是確定該對象在哈希表中的索引位置。hashCode() 定義在JDK的Object.java中,這就意味著Java中的任何類都包含有hashCode()函數。
散列表存儲的是鍵值對(key-value),它的特點是:能根據“鍵”快速的檢索出對應的“值”。這其中就利用到了散列碼!(可以快速找到所需要的對象)
為什么要有 hashCode
我們以“HashSet 如何檢查重復”為例子來說明為什么要有 hashCode:
當你把對象加入 HashSet 時,HashSet 會先計算對象的 hashcode 值來判斷對象加入的位置,同時也會與其他已經加入的對象的 hashcode 值作比較,如果沒有相符的hashcode,HashSet會假設對象沒有重復出現。但是如果發現有相同 hashcode 值的對象,這時會調用 equals()方法來檢查 hashcode 相等的對象是否真的相同。如果兩者相同,HashSet 就不會讓其加入操作成功。如果不同的話,就會重新散列到其他位置。這樣我們就大大減少了 equals 的次數,相應就大大提高了執行速度。
hashCode()與equals()的相關規定
如果兩個對象相等,則hashcode一定也是相同的
兩個對象相等,對兩個對象分別調用equals方法都返回true
兩個對象有相同的hashcode值,它們也不一定是相等的
因此,equals 方法被覆蓋過,則 hashCode 方法也必須被覆蓋
hashCode() 的默認行為是對堆上的對象產生獨特值。如果沒有重寫 hashCode(),則該 class 的兩個對象無論如何都不會相等(即使這兩個對象指向相同的數據)
對象的相等與指向他們的引用相等,兩者有什么不同?
對象的相等 比的是內存中存放的內容是否相等而 引用相等 比較的是他們指向的內存地址是否相等。
看完上述內容,你們對String類型等值比較引起的“==”、“equals()”和“hashCode”詳解有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。