1 对象值相等的比较: == vs equals.
(1) p==q 表示p和q两个引用是否指向同一个对象 (地址是否相等).
(2) p.equals(q) 表示p指向的对象和q指向的对象的值是否相等 (值是否相等).
注意: 如果不覆写 equals,默认的 equals 逻辑就是引用比较(相当于==).
Card p = new Card(1, "♠");
Card q = new Card(1, "♠");
Card o = p;
p ==o; // true
p ==q; // false
p.equals(o); // true
// 因为如果不覆写 equals,默认的 equals 逻辑就是引用比较
p.equals(q); // false
覆写equals后
(1) 如果传入的为 null 或者传入的对象类型不是 Card, 就返回 false.
(2) 按照类的实现目标完成比较,例如这里只要花色和数值一样,就认为是相同的牌.
@Override
public boolean equals(Object o) {
if (o == null || !(o instanceof Card)) {
return false;
}
Card c = (Card) o;
return (rank == c.rank) && suit.equals(c.suit);
}
p.equals(q); // true
注意: 实现两个比较器接口 Comparable和Comparator, 通过重写它们的compareTo()和compare()方法来实现自己的自定义比较.
2 Comparable是基于 自然顺序 比较对象大小的, 有一个compareTo() 方法(方法里面是一个参数).通过重写compareTo()方法实现需求.
class Card implements Comparable<Card> {
public String rank; // 点数
public String suit; // 花色
public Card(String rank, String suit) {
this.rank = rank;
this.suit = suit;
}
@Override //重写compareTo()方法
public int compareTo(Card o) {
if (o == null) {
// 一般认为 null 的值比较小
return 1;
}
return rank1 - rank2; //我们只比较点数,不比较花色.
}
public static void main(String[] args) {
Card p = new Card("3", "♠");
Card q = new Card("8", "♥");
Card o = p;
System.out.println(p.compareTo(q)); // -5
System.out.println(p.compareTo(o)); // 0
}
}
3 Comparator是基于 比较器 比较对象大小的. 有一个compare() 方法(里面是两个参数). 通过重写compare()方法实现需求.
class CardComparator implements Comparator<Card> {
public String rank; // 点数
public String suit; // 花色
public Card(String rank, String suit) {
this.rank = rank;
this.suit = suit;
}
@Override //重写compare()方法.
public int compare(Card o1, Card o2) {
if (o1 == o2) {
return 0;
}
if (o1 == null) {
return -1;
}
if (o2 == null) {
return 1;
}
return rank1 - rank2;
}
public static void main(String[] args) {
Card p = new Card("3", "♠");
Card q = new Card("8", "♥");
Card o = p;
注意这里:
CardComparator comparator = new CardComparator();
System.out.println(comparator.compare(p,q)); // -5.
}
}
5 Comparable.compareTo 侵入性比较强.
6 Comparator.compare 需要实现一个比较器对象,对类侵入性弱, 但对算法代码实现侵入性强.