【JAVA零基礎入門系列】Day15 對象的比較


  【JAVA零基礎入門系列】(已完結)導航目錄

  最近一直有事,博客也停筆了一段時間,十分抱歉。

  這一篇主要講講對象的比較,什么是對象的比較,我們知道兩個數值類型只需要用“==”符號即可進行相等判斷,但如果是兩個Goods對象呢?如何進行比較?這時候,我們的equals方法就派上用場了。equals方法是類的祖先Object類的另一個protected方法,既然是protected方法(能被同一個包里的所有類所訪問, 能被該類的子類所訪問,子類可以和父類不在一個包中),子類是可以直接訪問的,但如果沒有覆蓋該方法,那么使用的只是Object的原始比較方法,return(this==obj) ,僅僅比較兩個對象的地址是否一致。

  對於String類型,已經設計好了equals方法,所以我們只需要拿來用就可以了,如果是我們自定義的類,那就得重寫該方法來進行覆蓋,下面還是用Goods類來舉一個小栗子:

public class Goods { private String title; private double price; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } //構造器
    public Goods(String title, double price) { this.title = title; this.price = price; }
}

  這是簡化版的Goods類,有兩個私有成員變量以及它們的設置器,訪問器,還有一個構造器,下面我們來重寫父類的equals方法,判斷兩個Goods是否相等,邏輯上,我們只需要兩者標題和價格一致即可認為兩個商品是相等的(當然可以根據實際情況進行調整),下面我們來設計一下equals方法:

/** * @author Frank * @create 2017/11/20 * @description 被測試類,測試equals方法 */
public class Goods { private String title; private double price; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } //構造器
    public Goods(String title, double price) { this.title = title; this.price = price; } //覆蓋equals方法
 @Override public boolean equals(Object obj) { Goods tmp = (Goods) obj; if (price == tmp.getPrice() && title.equals(tmp.getTitle())){ return true; }else { return false; } } }

  這里我們覆蓋了父類的equals方法,在equals方法中將obj強制類型轉換為Goods類,再比較兩者價格和標題是否相等,只要都相等,則返回true,否則返回false,這也符合我們的需求,下面測試一下:

/** * @author Frank * @create 2017/11/20 * @description 測試類,用於測試equals方法 */
public class Test { public static void main(String[] args) { Goods a = new Goods("Java",100); Goods b = new Goods("C++",100); Goods c = new Goods("Java",100); System.out.println(a.equals(b)); System.out.println(a.equals(c)); } }

  輸出結果為:false  ture

  這樣我們就簡單的實現了equals方法,但是,這個equals方法並不完美,首先,由於我們傳入的是Object對象,所以並不知道它原本的類型是否為Goods類型,如果不是Goods類型,當然不能拿來比較,於是我們得先進行一下類型判斷:

@Override public boolean equals(Object obj) {//類型判斷
        if (obj.getClass() != this.getClass()){ return false; }else { Goods tmp = (Goods) obj; if (price == tmp.getPrice() && title.equals(tmp.getTitle())){ return true; }else { return false; } } }

 

  仍舊不完美,如果比較的對象就是自身或者兩者指向同一個對象的話,直接返回true即可:

@Override public boolean equals(Object obj) { //先檢測是否為自比較
        if ( this == obj || obj == null){ return true; } //類型判斷
        if (obj.getClass() != this.getClass()){ return false; }else { Goods tmp = (Goods) obj; if (price == tmp.getPrice() && title.equals(tmp.getTitle())){ return true; }else { return false; } } }

  現在就好很多了,那么此時我們調用equals方法跟使用”==“比較符號有什么區別呢,來看一個栗子:

public class Test { public static void main(String[] args) { Goods a = new Goods("Java",100); Goods b = new Goods("C++",100); Goods c = new Goods("Java",100); Goods d = a; System.out.println(a.equals(b)); System.out.println(a.equals(c)); System.out.println(a.equals(d)); System.out.println(a==b); System.out.println(a==c); System.out.println(a==d); } }

  輸出如下:

false
true
true
false
false
true

  對於前三個輸出應該沒什么問題,主要看后三個,這里用相等比較符時,判斷的僅僅是兩個變量存儲的內容是否一致,由於a、b、c、d均為引用類型,所以比較的僅僅是它們是否指向相同的對象,這里只有a跟d指向的是相同的對象,c雖然title和price都與a相同,但是跟a是兩個完全不同的對象,因此沒有返回的是false。

  另外,有人也許會問,做類型判斷的時候,為什么不用instanceof或者isInstance方法,這里簡單說明一下原因。instance判斷的是a對象是否和b對象屬於同一個類,或者有同一個父類,或者實現了同一個接口。isinstance方法則判斷兩種類型是否可以進行強轉。

  由於這個小栗子並沒有相關上下文,所以還是直接用getClass方法進行判斷比較穩妥,當然,以后可以根據具體實際情況進行修改。

  至此,equals方法講解完畢,很簡單吧。之后還是會繼續更新的,歡迎大家繼續關注!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM