關於Java中的equals方法
歡迎轉載,但是請填寫本人的部落格園原址
https://www.cnblogs.com/JNovice/p/9347099.html
一、什麼是equals方法
equals
方法是Object
類中的方法,根據Java的技術文件上的描述,其作用指示其他某個物件是否與此物件“相等”。
equals方法在非空物件引用上實現相等關係:
-
- 自反性:對於任何非空引用值 x,x.equals(x) 都應返回 true。
- 對稱性:對於任何非空引用值 x 和 y,當且僅當 y.equals(x) 返回 true 時,x.equals(y) 才應返回 true。
- 傳遞性:對於任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,並且 y.equals(z) 返回 true,那麼 x.equals(z) 應返回 true。
- 一致性:對於任何非空引用值 x 和 y,多次呼叫 x.equals(y) 始終返回 true 或始終返回 false,前提是物件上 equals 比較中所用的資訊沒有被修改。
- 對於任何非空引用值 x,x.equals(null) 都應返回 false
- Object 類的 equals 方法實現物件上差別可能性最大的相等關係;即,對於任何非空引用值 x 和 y,當且僅當 x 和 y 引用同一個物件時,此方法才返回 true(x == y 具有值 true)。
注意
:當此方法被重寫時,通常有必要重寫 hashCode 方法,以維護 hashCode 方法的常規協定,該協定宣告相等物件必須具有相等的雜湊碼。
引數
: obj - 要與之比較的引用物件。
返回
: 如果此物件與 obj 引數相同,則返回 true;否則返回 false。
二、equals的重寫
(一)為什麼要重寫equals方法
1 //Obeject未被重寫時equals方法的原始碼,StringBuffer的equals方法也是一樣的,也未重寫 2 public boolean equals(Object obj) { 3 return (this == obj); 4 }
- 從原始碼中我們可以看出,equals未被重寫的時候,它的作用是用來比較兩個引用資料型別的物件的引用是否相同。
- 但是我們實際開發中,更多的是兩個物件的具體數值是否相同,當兩個物件的具體值相同時,我們一般就認為它們是相等的,所以我們需要去重寫equals方法
(二)String
類中對equals方法的重寫
1 //個人String的equals方法的原始碼的簡單解讀 2 public boolean equals(Object anObject) { 3 if (this == anObject) {//先對地址值進行判斷 4 return true; 5 } 6 if (anObject instanceof String) {//判斷傳入是否是字串型別 7 String anotherString = (String)anObject; 8 int n = value.length;//此value時String的內部屬性,是儲存String字串的char型陣列 9 if (n == anotherString.value.length) {//判斷傳入的字串長度與本物件是否相等 10 char v1[ ] = value; 11 char v2[ ] = anotherString.value; 12 int i = 0; 13 while (n-- != 0) {//將字串的每個字元進行比較 14 if (v1[i] != v2[i]) 15 return false; 16 i++; 17 } 18 return true; 19 } 20 } 21 return false;//以上都沒有return的代表都不滿足if條件,最終返回false 22 } 23 }
- 我們再將String重寫過後的equals原始碼和和未重寫的進行比較,我們就可以發現重寫之後的String的equals方法是原方法的升級版。
- 首先它也對兩個引用進行了比較,同時也比較了String的具體數值,當滿足既是字串型別又和本字串的長度和具體內容全都相同時,那麼此時才返回true
(三)Java10.0
的String類的equals方法
1 //Java10.0版本對equals重寫的簡單解讀 2 public boolean equals(Object anObject) { 3 if (this == anObject) { 4 return true; 5 } 6 if (anObject instanceof String) { 7 String aString = (String)anObject; 8 if (coder() == aString.coder()) { 9 return isLatin1() ? StringLatin1.equals(value, aString.value)//這裡的Latin1是ISO-8859-1編碼格式的別稱 10 : StringUTF16.equals(value, aString.value); 11 } 12 } 13 return false; 14 }
- 這裡Java10.0版本對String類的equals方法進行了升級。
- 因為10.0版本的equals方法加入對編碼格式的判定,這裡的編碼格式是Latin1(別名ISO-8859-1)和UTF-16。
注:以下列舉幾個其他的編碼格式
- ASCII 英文字符集
- Unicode 國際通用字符集,注意Java語言是用Unicode編寫的
- UTF-8
8-bit Unicode Transformation Format是一種針對Unicode的可變長度字元編碼 - BIG5 臺灣的大五碼,表示繁體漢字
- GB2312 大陸使用最早、使用最廣的簡體中文字符集
- GBK GB2312的擴充套件,可以表示繁體中文
- GB18030 最新GBK擴充,中國所有非手持/嵌入式計算機系統的強制實施標準,可以表示漢字、維吾爾語、藏文等中華民族字元
三、
equals
方法和==
在判斷相等上的區別
==
既可以判斷基本資料型別,又可以判斷引用資料型別,判斷基本資料型別時是判斷值是否相等,而判斷引用資料型別時是判斷引用地址是否相等equals
方法只能判斷引用資料型別是否相等,在未被重寫時與==
的判斷方式一致,但是被重寫之後不僅判斷引用是否,而且判斷物件的具體屬性值是否相等
注:所有我們在判斷String等引用資料型別是否相等時時一般都是用重寫後的equals的方法,還有StringBuffer的equals方法未被重寫
- 以下是實際程式碼演示
1 public class TestClass { 2 3 public static void main(String[] args) { 4 String s1 = "123"; 5 String s2 = new String("123"); 6 System.out.println(s1 == s2);//由於s2是在堆空間的引用,因而和s1的引用地址不一樣 7 System.out.println(s1.equals(s2)); 8 //結果輸出 9 //false 10 //true 11 12 String s3 = "abc"; 13 String s4 = "abc"; 14 System.out.println(s3 == s4);//由於字串是不可變的,當常量池中有這個字串數值,就不再建立直接將引用給新的字串物件 15 System.out.println(s3.equals(s4)); 16 //結果輸出 17 //true 18 //true 19 } 20 21 }
注:補充下其他的資料型別如何對比
-
- 整型可以用==進行對比
- 字串用equals進行對比
- 浮點型可以使用BigDecimal或者浮點型的包裝類方法Float.floatToIntBits和Double.doubleToLongBits方法
- getHashCode方法