直接上操作。
1。使用默认比较器
PriorityQueue<int[]> pq=new PriorityQueue<>();
上面这段代码是建立了一个优先队列,在泛型<>中可以看到int[],这表示队列中的每个元素都是一个int型数组。使用了不带参数的构造方法来创建实例,表示使用了默认的比较方法。元素自己自行比较。
2。使用自定义的比较器
下面这段代码摘自廖雪峰老师的java教程中。
https://liaoxuefeng.com/books/java/collection/priority-queue/
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;
public class Main {
public static void main(String[] args) {
Queue<User> q = new PriorityQueue<>(new UserComparator());
// 添加3个元素到队列:
q.offer(new User("Bob", "A1"));
q.offer(new User("Alice", "A2"));
q.offer(new User("Boss", "V1"));
System.out.println(q.poll()); // Boss/V1
System.out.println(q.poll()); // Bob/A1
System.out.println(q.poll()); // Alice/A2
System.out.println(q.poll()); // null,因为队列为空
}
}
class UserComparator implements Comparator<User> {
public int compare(User u1, User u2) {
if (u1.number.charAt(0) == u2.number.charAt(0)) {
// 如果两人的号都是A开头或者都是V开头,比较号的大小:
return u1.number.compareTo(u2.number);
}
if (u1.number.charAt(0) == 'V') {
// u1的号码是V开头,优先级高:
return -1;
} else {
return 1;
}
}
}
class User {
public final String name;
public final String number;
public User(String name, String number) {
this.name = name;
this.number = number;
}
public String toString() {
return name + "/" + number;
}
}
看到User类,这是我们存入这个优先队列中的元素。
看到UerComparator类,这是我们编写比较器的类,它实现了Comparator接口,必须要实现Comparator接口中的compare方法。
看到创建PriorityQueue实例,在其中我们传入了创建的比较器的类的实例,因为PriorityQueue默认是使用Comparator接口的compare方法,所以PriorityQueue会找到该实例中的compare方法覆盖默认的compare方法作为新的比较器。
看到比较器类的compare方法,有两个参数,记住,第一个参数永远是新的参数,插入的时候就是插入的参数,删除的时候就是被删除的参数,然后第二个参数就是依次与之比较的参数。其中的逻辑是compare返回时负值的时候,表示要交换,否则表示不要交换。所以默认是小根堆,如果传入进来的是小的元素,则不断比较的过程中,会进行不断地交换。
小顶堆,
return
前减后(o1-o2);
大顶堆,return
后减前(o2-o1);
由于PriorityQueue是使用大根堆或者小根堆实现的,所以该比较器是用来在创建堆的时候判断大小来移动元素用的,具体逻辑可以自行去结合堆排序来思考。