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方法来完成对应类型的比较;
  • 对代码侵入性较小,不需要修改源代码