在Java中,我們常常涉及到對象的比較問題,總體來說就兩種:一種是比較是否相等,另一種就是比較兩個對象之間的大小關係。接下來一一介紹:
一、相等比較
通常我們在比較兩個對象是否相等時,用到的就是“==”運算符和Object類下的equals方法。有關於這二者的區別,大家可以參考我的另一篇博客—>hashCode,equals,== 三者的區別是什麼?
這裏簡單的來說,==運算符通常是比較兩個引用是否指向同一個對象,而equals方法可以通過自己覆寫來比較兩個對象中對應的值是否相等。
二、大小比較
1.Comparable< E > —— 基於自然順序
Comparable是一個接口,想要對一個實例對象使用該比較器就要實現Comparable接口下的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;
}
@Override
public int compareTo(Card o) {
if(o == null){
return 1;
}
return rank - o.rank;
}
}
2.Comparator< T > —— 基於比較器
Coomparator同樣是一個接口,如果類實現了comparator接口就可以自定義的傳入比較器對兩個對象進行比較
import java.util.Comparator;
public class Card2 {
public int rank;
public String suit;
public Card2(int rank, String suit) {
this.rank = rank;
this.suit = suit;
}
public static void main(String[] args) {
Card2 c1 = new Card2(1,"♥");
Card2 c2 = new Card2(7,"♣");
Card2 c3 = new Card2(7,"♦");
Card2 c4 = new Card2(2,"♠");
Comparator<Card2> cmp = new CardComparator();
cmp.compare(c1,c2);
cmp.compare(c2,c3);
cmp.compare(c3,c4);
}
}
class CardComparator implements Comparator<Card2>{
@Override
public int compare(Card2 o1, Card2 o2) {
if(o1 == o2){
return 0;
}
if(o1 == null){
return -1;
}
if (o2 == null){
return 1;
}
return o1.rank - o2.rank;
}
}
在使用時,我們是傳入或者調用一個自己設計的Comparator對象,使用它的compare方法來進行比較。
對於compare方法傳入o1和o2兩個待比較對象,其返回值:
- 大於0 表示 o1 > o2
- 小於0 表示 o1 < o2
- 等於0 表示 o1 = o2
覆寫的方法 | 說明 |
---|---|
Object.equals | 因爲所有類都是繼承自 Object 的,所以直接覆寫即可,不過只能比較相等與否 |
Comparable.compareTo | 需要手動實現接口,侵入性比較強,但一旦實現,每次用該類都有順序,屬於內部順序 |
Comparator.compare | 需要實現一個比較器對象,對待比較類的侵入性弱,但對算法代碼實現侵入性強 |
三、和框架相結合
- 使用 contains 類似的方法,內部基本在調用元素的 equals 方法,所以要求元素覆寫過 equals 方法
- 使用 HashMap,key 的比較內部會調用 equals 方法,所以要求元素覆寫過 equals 方法
- 使用排序相關方法,內部需要進行比較,所以或者選擇實現 Comparable 或者傳入一個 Comparator
- 使用 TreeMap,key 需要進行大小比較,所以或者選擇實現 Comparable 或者傳入一個 Comparator