1. 关于对象值相等的比较
1.1 == vs equals
p == q 表示的是 p 和 q 两个引用指向同一个对象
p.equals(q) 表示 p 指向的对象 和 q 指向的对象是否是值语义相等的
1.2 示例
覆写 equals 前
public class Card { public int rank; // 数值 public String suit; // 花色 public Card(int rank, String suit) { this.rank = rank; this.suit = suit; } }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,默认的 equals 逻辑就是引用比较

覆写 equals 后
public class Card { public int rank; // 数值 public String suit; // 花色 public Card(int rank, String suit) { this.rank = rank; this.suit = suit; } }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,默认的 equals 逻辑就是引用比较

注意: 一般覆写 equals 的套路就是上面演示的

如果指向同一个对象,返回 true如果传入的为 null,返回 false如果传入的对象类型不是 Card,返回 false按照类的实现目标完成比较,例如这里只要花色和数值一样,就认为是相同的牌注意下调用其他引用类型的比较也需要 equals,例如这里的 suit 的比较
2. 关于对象值大于、等于、小于的比较-基于自然顺序
认识Comparable<E>

````public interface Comparable<E>{ // 返回值: // < 0: 表示 this 指向的对象小于 o 指向的对象// == 0: 表示 this 指向的对象等于 o 指向的对象// > 0: 表示 this 指向的对象等于 o 指向的对象 int compareTo(E o); }`

示例:
**```
```

`public class Card implements Comparable<Card> { public int rank; // 数值public String suit; // 花色 public Card(int rank, String suit) { this.rank = rank; this.suit = suit;}// 根据数值比较,不管花色// 这里我们认为 null 是最小的 @Override public int compareTo(Card o) {if (o == null) { return 1;}return rank - o.rank;}}`**```

``Card p = new Card(1, "♠"); Card q = new Card(2, "♠"); Card o = new Card(1, "♠");p.compareTo(o); // == 0,表示牌相等p.compareTo(q); // < 0,表示 p 比较小q.compareTo(p); // > 0,表示 q 比较大

3. 关于对象值大于、等于、小于的比较-基于比较器**3.1 认识 Comparator<T>

public interface Comparator<T> { // 返回值:// < 0: 表示 o1 指向的对象小于 o2 指向的对象// == 0: 表示 o1 指向的对象等于 o2 指向的对象// > 0: 表示 o1 指向的对象等于 o2 指向的对象int compare(T o1, T o2);}

3.2 示例

public class Card implements Comparable<Card> { public int rank; // 数值 public String suit; // 花色public Card(int rank, String suit) {this.rank = rank; this.suit = suit;}// 根据数值比较,不管花色// 这里我们认为 null 是最小的@Override public int compareTo(Card o){if (o == null) { return 1;}return rank - o.rank;} }Card p = new Card(1, "♠");Card q = new Card(2, "♠"); Card o = new Card(1, "♠"); p.compareTo(o); // == 0,表示牌相等 p.compareTo(q); // < 0,表示 p 比较小q.compareTo(p); // > 0,表示 q 比较大

4. 比较

覆写的方法 及说明Object.equals //因为所有类都是继承自 Object 的,所以直接覆写即可,不过只能比较相等与否Comparable.compareTo//需要手动实现接口,侵入性比较强,但一旦实现,每次用该类都有顺序,属于内部顺序Comparator.compare//需要实现一个比较器对象,对待比较类的侵入性弱,但对算法代码实现侵入性强

** 5和 java 集合框架的配合**1. 使用 contains 类似的方法,内部基本在调用元素的 equals 方法,所以要求元素覆写过 equals 方法2. 使用 HashMap,key 的比较内部会调用 equals 方法,所以要求元素覆写过 equals 方法3. 使用排序相关方法,内部需要进行比较,所以或者选择实现 Comparable 或者传入一个 Comparator4. 使用 TreeMap,key 需要进行大小比较,所以或者选择实现 Comparable 或者传入一个 Comparator5. 其他规则以此类推