一.PriorityQueue中插入对象
优先级队列在插入元素时有个要求:插入的元素不能是null或者元素之间必须要能够进行比较,那优先级队列中能否插入自定义类型对象呢?
堆中插入元素时,必须要进行元素的比较,而此时Card是没有办法直接进行比较的,因此会抛出异常
二.元素的比较
1.基本元素类型的比较
在Java中,基本类型的对象可以直接比较大小
2.对象比较的问题
public class Card {
public int rank; //数值
public String suit; //花色
public Card(int rank, String suit) {
this.rank = rank;
this.suit = suit;
}
}
public class Test{
public static void main(String[] args) {
Card c1 = new Card(1,"♥");
Card c2 = new Card(1,"♥");
Card c3 = c1;
//System.out.println(c1 > c2); 编译报错
System.out.println(c1 == c2); //打印false,因为c1和c2指向的是不同的对象
//System.out.println(c1 < c2);编译报错
System.out.println(c1 == c3); //打印true,应为c1和c3指向同一个对象
System.out.println(c1.equals(c2)); //打印false,因为c1和c2指向的是不同的对象
}
}
三.对象的比较
有些情况下,需要比较对象中的内容
1.覆写基类的equals(比较是否相等)
右键生成equls重写方法
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 object) {
if (this == object) return true;
if (object == null || getClass() != object.getClass()) return false;
Card card = (Card) object;
return rank == card.rank && Objects.equals(suit, card.suit);
}
}
public class Test{
public static void main(String[] args) {
Card c1 = new Card(1,"♥");
Card c2 = new Card(1,"♥");
Card c3 = c1;
//System.out.println(c1 > c2); 编译报错
System.out.println(c1 == c2); //打印false,因为c1和c2指向的是不同的对象
//System.out.println(c1 < c2);编译报错
System.out.println(c1 == c3); //打印true,应为c1和c3指向同一个对象
System.out.println(c1.equals(c2));//打印true,因为c1和c2里面的内容一致
System.out.println(c1.rank == c2.rank);//打印true,因为rank相同
}
}
2.基于Comparble接口类的比较(比较大小)
源码实现:
对于用户自定义类型,如果要按照大小与方式进行比较时:在定义类时,实现Comparble接口即可,然后在类中重写compareTo方法
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 this.rank - o.rank;
}
}
public class Test{
public static void main(String[] args) {
Card p = new Card(1,"♥");
Card q = new Card(2,"♥");
Card o = new Card(1,"♥");
System.out.println(p.compareTo(o));//==0,表示牌相等
System.out.println(p.compareTo(q));//<0,表示p比较小
System.out.println(q.compareTo(p));//>0,表示q比较大
//System.out.println(q > p);//编译错误
}
}
Compareble是Java.lang中接口,可以直接使用
3.基于比较器比较
按照比较器进行比较,具体步骤如下:
- 用户自定义比较器类,实现Comparator接口
public interface Comparator<T> {
//返回值
//<0表示o1指向的对象小于o2指向的对象
//==0表示o1指向的对象等于o2指向的对象
//>0表示o1指向的对象大于o2指向的对象
int compare(T o1, T o2);
}
注意区分Comparator和Comparable
- 覆写Comparator中的compare方法
public class CardComparator implements Comparator<Card>{
//根据数值比较,不管花色
//这里我们认为null是最小的
@Override
public int compare(Card o1, Card o2) {
if (o1 == o2) {
return 0;
}
if (o1 == null) {
return -1;
}
if (o2 == null) {
return 1;
}
return o1.rank - o2.rank;
}
}
public class Test{
public static void main(String[] args) {
Card p = new Card(1,"♥");
Card q = new Card(2,"♥");
Card o = new Card(1,"♥");
//定义比较器对象
CardComparator cmptor = new CardComparator();
//使用比较器对象进行比较
System.out.println(cmptor.compare(p,o));//==0,表示牌相等
System.out.println(cmptor.compare(p,q));//<0,表示p比较小
System.out.println(cmptor.compare(q,p));//>0,表示q比较大
}
}
注意:Comparator是java.util包中的泛型接口类,使用时必须导入相应的包