关于priorityQueue:
1、priorityQueue里不能放null,要放可以比较的值
class Card { public int rank; // 数值 public String suit; // 花色 public Card(int rank, String suit) { this.rank = rank; this.suit = suit; } } public class TestDemo { public static void main(String[] args) { PriorityQueue<Card> priorityQueue=new PriorityQueue<>();//默认是小根堆 priorityQueue.offer(new Card(1,"♥")); priorityQueue.offer(null);//会报错,priorityQueue里不能放null,要放可以比较的值 } }
2、priorityQueue底层数组的初始容量为11
扩容时:若原先容量小于64——》新容量=原先容量*2+2
若原先容量大于64——》新容量=原先容量*1.5
一、关于对象的比较
1、用implements实现比较接口Comparable(要重写compareTo方法)
缺点:对类的侵入性太强了,一旦写好了根据那种规则进行比较就不能轻易修改了
class Card implements Comparable<Card> {//要想比较自定义类型,需要自己重写比较方法 public int rank; // 数值 public String suit; // 花色 public Card(int rank, String suit) { this.rank = rank; this.suit = suit; } public int compareTo(Card o) {//重写比较方法 return this.rank-o.rank;//默认小堆的比较方法 //return o.rank-this.rank;大堆的比较方法 } public static void main(String[] args) { Card card1=new Card(2,"♥"); Card card2=new Card(1,"♥"); System.out.println(card1.compareTo(card2));//比较大小 }
2、单独实现一个比较器Comparator(需要写比较方法compare)
class Card { public int rank; // 数值 public String suit; // 花色 public Card(int rank, String suit) { this.rank = rank; this.suit = suit; } class RankComparator implements Comparator<Card> {//单独实现一个比较器 @Override public int compare(Card o1, Card o2) {//写一个比较方法 return o1.rank-o2.rank; } } public static void main(String[] args) { Card card1=new Card(2,"♥"); Card card2=new Card(1,"♥"); RankComparator rankComparator=new RankComparator();//实例化比较器对象 int ret=rankComparator.compare(card1,card2);//根据对象调用方法来比较大小 System.out.println(ret); }
3、用equals比较对象:只能知道是否相同,相同返回true,不同返回false
public static void main(String[] args) { Card card1=new Card(1,"♥"); Card card2=new Card(1,"♥"); System.out.println(card1.equals(card2));//输出false,因为没有重写equals方法,默认调用object的equals方法,比较的是地址 } //要想根据花色和数字来判断两张牌的内容是否相同,需要重写equals方法 class Card { public int rank; // 数值 public String suit; // 花色 public Card(int rank, String suit) { this.rank = rank; this.suit = suit; } @Override重写的equals方法 public boolean equals(Object o) { if (this == o) return true;//如果引用的是同一个对象,返回true if (o == null || getClass() != o.getClass()) return false;//getClass() != o.getClass()看是否为同一个类型,不能Card根Person比较 Card card = (Card) o;//因为o是object类型,需要强转 return rank == card.rank && Objects.equals(suit, card.suit); } @Override public int hashCode() { return Objects.hash(rank, suit); } }
注意:如果是自定义类型,若要根据内容判断是否相同,需要重写equals方法
二、对于 priorityQueue如何自定义小堆还是大堆,只需要创建时传入一个小堆的比较器,或大堆的比较器即可
//法一:直接实现一个比较器,然后再使用队列时传入比较器
class RankComparator implements Comparator<Card> {//单独实现一个比较器
@Override
public int compare(Card o1, Card o2) {//写一个比较方法
return o1.rank-o2.rank;//实现小堆,要实现大堆,则return o2.rank-o1.rank;
}
}
public static void main(String[] args) {
Card card1=new Card(2,"♥");
Card card2=new Card(1,"♥");
RankComparator rankComparator=new RankComparator();//实例化比较器
PriorityQueue<Card> priorityQueue=new PriorityQueue<>(rankComparator);//传入比较器,就可以根据比较器来自定义小堆比较还是大堆比较了
priorityQueue.offer(card1);
priorityQueue.offer(card2);
System.out.println(priorityQueue);
}
//法二:用内部类的方法,再使用队列时传入一个内部类,在内部类里写一个比较方法
public static void main(String[] args) {
Card card1=new Card(2,"♥");
Card card2=new Card(1,"♥");
PriorityQueue<Card> priorityQueue=new PriorityQueue<>(new Comparator<Card>() {
@Override
public int compare(Card o1, Card o2) {
return o1.rank-o2.rank;//实现小堆,要实现大堆,则return o2.rank-o1.rank;
}
});
priorityQueue.offer(card1);
priorityQueue.offer(card2);
System.out.println(priorityQueue);
}
//法三:用lambda表达式实现内部类
PriorityQueue<Card>priorityQueue1=new PriorityQueue<>((x,y)->{return x.rank-y.rank;});
三、PriorityQueue底层插入数据操作过程