1. 程式人生 > >零基礎入門學習java第十五節:對象的比較

零基礎入門學習java第十五節:對象的比較

obj println lse 來看 filter () 情況 轉換 行修改

這一篇主要講講對象的比較,什麽是對象的比較,我們知道兩個數值類型只需要用“==”符號即可進行相等判斷,但如果是兩個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方法講解完畢,很簡單吧。之後還是會繼續更新的,歡迎大家繼續關註!

零基礎入門學習java第十五節:對象的比較