在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