元素的比较对象的比较
equalsCompareTo通过比较器比较直接 new 一个比较器来比较重写 equals 方法来比较
元素的比较在 Java 当中,基本类型的对象可以直接比较大小。代码如下:
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println(a > b);
System.out.println(a < b);
System.out.println(a == b);
System.out.println();
char c1 = 'A';
char c2 = 'B';
System.out.println(c1 > c2);
System.out.println(c1 < c2);
System.out.println(c1 == c2);
System.out.println();
boolean b1 = true;
boolean b2 = false;
System.out.println(b1 == b2);
System.out.println(b1 != b2);
}
运行结果如下:
这里就可以完成比较。
equals 是比较两个对象相不相同。
CompareToCompareTo 用来比较大小。在之前实现对对象的比较的时候 ,要实现 Comparable 接口,而且要重写 Comparable 方法才可以比较。
代码如下:
class Card implements Comparable{ public int rank;//数值 public String suit;//花色 public Card(int rank, String suit) { this.rank = rank; this.suit = suit; } @Override public int compareTo(Card o) { //这里的排序换一下,就变成大堆排序了 return this.rank - o.rank; } @Override public String toString() { return "Card{" + "rank=" + rank + ", suit='" + suit + ''' + '}'; } } public class Main { public static void main(String[] args) { PriorityQueue priorityQueue = new PriorityQueue<>(); priorityQueue.offer(new Card(2, "♥"));// priorityQueue.offer(new Card(1, "♥")); System.out.println(priorityQueue); } }
运行结果如下:
因为实现了 Comparable 接口,所以就可以比较了。因为如果不实现 Comparable 接口的话,就会报错,因为无法转化为可以比较的类型。这里的 Comparable 是比较 rank 也就是比较数值,
但是这样写的缺点就是:把类写死了,只能这样通过数值比较。对类的侵入性太强了。所以就可以单独写一个比较器来实现比较方法。
通过比较器比较实现单独的比较器方法来比较。
代码如下:
class RankComparator implements Comparator{ @Override public int compare(Card o1, Card o2) { return o1.rank - o2.rank; } } public static void main(String[] args) { Card card1 = new Card(1,"♥"); Card card2 = new Card(2,"♥"); RankComparator rankComparator = new RankComparator(); PriorityQueue priorityQueue = new PriorityQueue<>(); priorityQueue.offer(card1); priorityQueue.offer(card2); System.out.println(priorityQueue); }
这里就是通过比较器去比较,运行结果如下:
只要是 o1 - o2 就是小根堆,否则就是大根堆。
因为可以在比较的时候使用 new 出来的比较器,那么也可以在使用方法的时候,在方法里面 new 一个比较器。代码如下:
public static void main(String[] args) {
Card card1 = new Card(1,"♥");
Card card2 = new Card(2,"♥");
//重写了 Comparator 方法 是一个匿名内部类
PriorityQueue priorityQueue = new PriorityQueue<>(new Comparator() {
public int compare(Card o1, Card o2) {
return o1.rank - o2.rank;
}
});
priorityQueue.offer(card1);
priorityQueue.offer(card2);
System.out.println(priorityQueue);
}
这里通过重写 Compare 方法来实现比较。运行结果如下:
当然也可以把比较代码简写成这种 lambda 表达式,但是这样的代码的可读性非常差:
PriorityQueue重写 equals 方法来比较priorityQueue = new PriorityQueue<>((x, y)-> { return y.rank - x.rank; });
当花色和数字一样的时候,我们就认为一样,但是如果不重写 equals 方法的话,就会比较地址,是 false 。在 idea 当中,重写 equals 方法的话,一直下一步就好了。代码如下:
class Card implements Comparable{ public int rank;//数值 public String suit;//花色 public Card(int rank, String suit) { this.rank = rank; this.suit = suit; } @Override public int compareTo(Card o) { //这里的排序换一下,就变成大堆排序了 return this.rank - o.rank; } @Override public String toString() { return "Card{" + "rank=" + rank + ", suit='" + suit + ''' + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Card card = (Card) o; return rank == card.rank && Objects.equals(suit, card.suit); } @Override public int hashCode() { return Objects.hash(rank, suit); } } public static void main(String[] args) { Card card1 = new Card(1,"♥"); Card card2 = new Card(1,"♥");//不重写 equals 方法的话,默认比较的是引用 //重写之后 就是自定义比较了 System.out.println(card1.equals(card2)); }
运行结果如下:



