您好,登錄后才能下訂單哦!
這篇文章主要介紹了Java中對象比較的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
在Java中,基本類型的對象可以直接比較大小
public class TestCompare { public static void main(String[] args) { int a = 10; int b = 20; System.out.println(a > b); System.out.println(a < b); System.out.println(a == b); char c1 = 'A'; char c2 = 'B'; System.out.println(c1 > c2); System.out.println(c1 < c2); System.out.println(c1 == c2); boolean b1 = true; boolean b2 = false; System.out.println(b1 == b2); System.out.println(b1 != b2); } }
先來看一段代碼
class Card { public int rank; // 數值 public String suit; // 花色 public Card(int rank, String suit) { this.rank = rank; this.suit = suit; } } public class TestPriorityQueue { public static void main(String[] args) { Card c1 = new Card(1, "?"); Card c2 = new Card(2, "?"); Card c3 = c1; //System.out.println(c1 > c2); // 編譯報錯 System.out.println(c1 == c2); // 編譯成功 ----> 打印false,因為c1和c2指向的是不同對象 //System.out.println(c1 < c2); // 編譯報錯 System.out.println(c1 == c3); // 編譯成功 ----> 打印true,因為c1和c3指向的是同一個對象 } }
c1、c2和c3分別是Card類型的引用變量,上述代碼在比較編譯時:
c1 > c2 編譯失敗c1== c2 編譯成功c1 < c2 編譯失敗
從編譯結果可以看出,Java中引用類型的變量不能直接按照 > 或者 < 方式進行比較。
那為什么== 可以比較?
因為:對于用戶實現自定義類型,都默認繼承自Object類,而Object類中提供了equal方法,而 equal方法 在不覆寫的情況下,默認用的就是 ==
該方法的比較規則是:
沒有比較引用變量引用對象的內容,而是直接比較引用變量的地址
但有些情況下用equals方法來比較就不符合題意。需要進行覆寫,修改成我們所需要的比較方法
有些情況下,需要比較的是對象中的內容,比如:
向優先級隊列中插入某個對象時,需要堆按照對象中內容來調整堆,那該如何處理呢?
以下提供三種比較對象的方式
public class Card { public int rank; // 數值 public String suit; // 花色 public Card(int rank, String suit) { this.rank = rank; this.suit = suit; } @Override public boolean equals(Object o) { // 自己和自己比較 if (this == o) { return true; } // o如果是null對象,或者o不是Card的子類 if (o == null || !(o instanceof Card)) { return false; }// 注意基本類型可以直接比較,但引用類型最好調用其equal方法 Card c = (Card)o; return rank == c.rank && suit.equals(c.suit); } }
注意: 一般覆寫 equals 的套路就是上面演示的
如果指向同一個對象,返回 true
如果傳入的為 null,返回 false
如果傳入的對象類型不是 Card,返回 false
按照類的實現目標完成比較,例如這里只要花色和數值一樣,就認為是相同的牌
注意下調用其他引用類型的比較也需要 equals,例如這里的 suit 的比較
覆寫基類equal的方式雖然可以比較,但缺陷是:equal只能按照相等進行比較,不能按照大于、小于的方式進行比較。
Comparble是JDK提供的泛型的比較接口類,源碼實現具體如下:
對用用戶自定義類型,如果要想按照大小與方式進行比較時:在定義類時,實現Comparble接口即可,然后在類中重寫compareTo方法。
public class Card implements Comparable<Card> { public int rank; // 數值 public String suit; // 花色 public Card(int rank, String suit) { this.rank = rank; this.suit = suit; } // 根據數值比較,不管花色 // 這里我們認為 null 是最小的 @Override public int compareTo(Card o) { if (o == null) { return 1; } return rank - o.rank; } public static void main(String[] args) { Card p = new Card(1, "?"); Card q = new Card(2, "?"); Card o = new Card(1, "?"); System.out.println(p.compareTo(o)); // == 0,表示牌相等 System.out.println(p.compareTo(q)); // < 0,表示 p 比較小 System.out.println(q.compareTo(p)); // > 0,表示 q 比較大 } }
Compareble是java.lang中的接口類,可以直接使用
Comparator接口源碼如下:
按照比較器方式進行比較,具體步驟如下:
用戶自定義比較器類,實現Comparator接口
class CardComparator implements Comparator<Card> { // 根據數值比較,不管花色 // 這里我們認為 null 是最小的 ******************** //覆寫代碼區 ******************** }
注意:區分Comparable和Comparator。
覆寫Comparator中的compare方法
@Override public int compare(Card o1, Card o2) { if (o1 == o2) { return 0; } if (o1 == null) { return -1; } if (o2 == null) { return 1; } return o1.rank - o2.rank; }
調用自定義的比較器
public static void main(String[] args){ Card p = new Card(1, "?"); Card q = new Card(2, "?"); Card o = new Card(1, "?"); // 定義比較器對象 CardComparator cmptor = new CardComparator(); // 使用比較器對象進行比較 System.out.println(cmptor.compare(p, o)); // == 0,表示牌相等 System.out.println(cmptor.compare(p, q)); // < 0,表示 p 比較小 System.out.println(cmptor.compare(q, p)); // > 0,表示 q 比較大 }
注意:Comparator是java.util 包中的泛型接口類,使用時必須導入對應的包。
三種比較方式對比
覆寫的方法 | 說明 |
---|---|
Object.equals | 因為所有類都是繼承自 Object 的,所以直接覆寫即可,不過只能比較相等與否 |
Comparable.compareTo | 需要手動實現接口,侵入性比較強,但一旦實現,每次用該類都有順序,屬于內部順序 |
Comparator.compare | 需要實現一個比較器對象,對待比較類的侵入性弱,但對算法代碼實現侵入性強 |
集合框架中的PriorityQueue底層使用堆結構,因此其內部的元素必須要能夠比大小,PriorityQueue采用了:Comparble和Comparator兩種方式。
Comparble是默認的內部比較方式,如果用戶插入自定義類型對象時,該類對象必須要實現Comparble接口,并覆寫compareTo方法
用戶也可以選擇使用比較器對象,如果用戶插入自定義類型對象時,必須要提供一個比較器類,讓該類實現Comparator接口并覆寫compare方法。
感謝你能夠認真閱讀完這篇文章,希望小編分享的“Java中對象比較的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。