作者:~小明学编程
文章专栏:Java数据结构
格言:目之所及皆为回忆,心之所想皆为过往
目录
比较器的比较
equals的比较
三种方式的比较
class Card {public int rank; // 数值public String suit; // 花色public Card(int rank, String suit) {this.rank = rank;this.suit = suit;}@Overridepublic String toString() {return "Card{" +"rank=" + rank +", suit='" + suit + '\'' +'}';}
}
class RankComparator implements Comparator {@Overridepublic int compare(Card o1,Card o2) {return o1.rank - o2.rank;}
}public class Test {public static void main(String[] args) {Card card1 = new Card(2,"♠");Card card2 = new Card(3,"♠");RankComparator rankComparator = new RankComparator();rankComparator.compare(card1,card2);}
}
比较器的用法就如上述的代码所示,我们首先构造一个类然后实现我们的Comparator的接口,接着就是重写我们里面的compare方法,然后就可以用它进行比较了。
当然我们在使用优先级队列的时候可以直接向里面传入我们的比较器。
public static void main(String[] args) {//默认是一个小堆RankComparator rankComparator = new RankComparator();PriorityQueue priorityQueue = new PriorityQueue<>(rankComparator);
}
当然这样写可能会觉得麻烦,因为我们首先要写一个类,然后还要我们的类来实现接口然后重写方法,那么有没有简单点的写法呢?
public static void main(String[] args) {//默认是一个小堆PriorityQueue priorityQueue2 = new PriorityQueue<>(new Comparator() {@Overridepublic int compare(Card o1, Card o2) {return o1.rank - o2.rank;}});
}
我们可以运用内部类的写法,就是在我们new一个接口的时候就直接重写我们的compare方法。
PriorityQueue priorityQueue1 = new PriorityQueue<>((x,y)-> {return x.rank - y.rank;});
当然,还有更加简单的写法,lambda的写法,不过这种写法过于的抽象不建议用。
public static void main(String[] args) {Card card1 = new Card(3,"♠");Card card2 = new Card(3,"♠");System.out.println(card1.equals(card2));
}
结果意料之外情理之中,咋一看我们的两个对象的数字和花色都一样,但是为什么会返回一个false呢?我们点开源码看一下就知道了。
public boolean equals(Object obj) {return (this == obj);}
这里equals比较的是一个地址,我们两个对象的地址不一样所以就是false,这时候我们重写一下我们的equals()方法。
@Overridepublic 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);}
简单解析一下源码,首先是比较我们的地址地址一样的话,那么直接返回true,接着就是判断类型,类型不一样直接返回false,最后就是判断花色和数字,返回我们能的结果。
覆写的方法 | 说明 |
Object.equals | 因为所有类都是继承自 Object 的,所以直接覆写即可,不过只能比较相等与 否 |
Comparable.compareTo | 需要手动实现接口,侵入性比较强,但一旦实现,每次用该类都有顺序,属于 内部顺序 |
Comparator.compare | 需要实现一个比较器对象,对待比较类的侵入性弱,但对算法代码实现侵入性 强 |