Java对象的三种比较方式
- 一、重写equals方法
- 1.equals与==的比较
- 2.示例
- 3.注意
- 4.特性
- 二、实现comparable接口类
- 1.认识comparable
- 2.示例
- 3.特性
- 三、重写comparator
- 1.认识comparator
- 2.示例
- 3.特性
在Java中,8种基本类型及其所对应的包装类型都可以直接比较其大小,那用户自定义的类型能不能直接比较大小呢?显然不能,因为标准库中带有可以直接比较基本类型的方法,而对于用户自定义的类型,标准库并不知道类对象中有哪些成员,应该找那个成员进行比较。因此,如果要实现用户自定义类型的比较,需要用到以下三种方法之一。
一、重写equals方法
1.equals与==的比较
- ==表示判断两个对象的引用是否指向同一个对象;
- equals判断两个对象的内容是否相同。
2.示例
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 == 0) {
return true;
}
if (o == null || !(o instanceof Card)) {
return false;
}
Card c = (Card)o;
return rank == c.rank && suit.equals(c.suit);
}
}
Card p = new Card(1, "♠");
Card q = new Card(1, "♠");
Card o = p;
p == o; // true
p == q; // false
p.equals(o); // true
p.equals(q); // true
3.注意
一般覆写 equals 的方法就是上面演示的
- 如果指向同一个对象,返回 true
- 如果传入的为 null,返回 false
- 如果传入的对象类型不是 Card,返回 false
- 按照类的实现目标完成比较,例如这里只要花色和数值一样,就认为是相同的牌
- 注意下调用其他引用类型的比较也需要 equals,例如这里的 suit 的比较
4.特性
只能进行==,不能进行自然次序的比较(大于或小于)
二、实现comparable接口类
1.认识comparable
public interface Comparable<E> {
// 返回值:
// < 0: 表示 this 指向的对象小于 o 指向的对象
// == 0: 表示 this 指向的对象等于 o 指向的对象
// > 0: 表示 this 指向的对象等于 o 指向的对象
int compareTo(E o);
}
2.示例
class Card implements Comparable<Card>{
public int rank;
public String suit;
public Card(int rank, String suit){
this.rank = rank;
this.suit = suit;
}
public int compareTo(Card o){
return rank - o.rank;
}
C
ard p = new Card(1, "♠");
Card q = new Card(2, "♠");
Card o = new Card(1, "♠");
Comparator<Card> cmptor = new CardComparator();
cmptor.compare(p, o); // == 0,表示牌相等
cmptor.compareTo(p, q); // < 0,表示 p 比较小
cmptor.compareTo(q, p); // > 0,表示 q 比较大
3.特性
- 可以按照自然次序进行比较
- 对代码的侵入性比较强(需要修改源代码);如果类是用户自己实现的,就可以使用,如果不是则不能使用该种方式
三、重写comparator
1.认识comparator
public interface Comparator<T> {
// 返回值:
// < 0: 表示 o1 指向的对象小于 o2 指向的对象
// == 0: 表示 o1 指向的对象等于 o2 指向的对象
// > 0: 表示 o1 指向的对象等于 o2 指向的对象
int compare(T o1, T o2);
}
2.示例
class CardComp implements Comparator<Card>{
public int compare(Card o1, Card o2){
if(o1 == o2){
return 0;
}
if(o1 == null){
return -1;
}
if(o2 == null){
return 1;
}
return o2.rank - o1.rank;
}
C
ard p = new Card(1, "♠");
Card q = new Card(2, "♠");
Card o = new Card(1, "♠");
Comparator<Card> cmptor = new CardComparator();
cmptor.compare(p, o); // == 0,表示牌相等
cmptor.compareTo(p, q); // < 0,表示 p 比较小
cmptor.compareTo(q, p); // > 0,表示 q 比较大
3.特性
- 先要创建一个比较器的对象,然后让比较器对象调用compare方法来完成对应类型的比较;
- 对代码侵入性较小,不需要修改源代码