關於Java中的equals方法

JNovice發表於2018-07-21

 

關於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 }

  1. 從原始碼中我們可以看出,equals未被重寫的時候,它的作用是用來比較兩個引用資料型別的物件的引用是否相同。
  2. 但是我們實際開發中,更多的是兩個物件的具體數值是否相同,當兩個物件的具體值相同時,我們一般就認為它們是相等的,所以我們需要去重寫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 }
  1. 我們再將String重寫過後的equals原始碼和和未重寫的進行比較,我們就可以發現重寫之後的String的equals方法是原方法的升級版。
  2. 首先它也對兩個引用進行了比較,同時也比較了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 }
  1. 這裡Java10.0版本對String類的equals方法進行了升級。
  2. 因為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方法和==在判斷相等上的區別

  1. ==既可以判斷基本資料型別,又可以判斷引用資料型別,判斷基本資料型別時是判斷值是否相等,而判斷引用資料型別時是判斷引用地址是否相等
  2. 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方法

相關文章