PriorityQueue 一个基于优先级的无界优先级队列。内部使用 Object 数组实现,默认大小是 11。
PriorityQueue 通过二叉小顶堆实现,具体说是通过完全二叉树(complete binary tree)实现的小顶堆(任意一个非叶子节点的权值,都不大于其左右子节点的权值)
优先级队列的元素按照其自然顺序(从小到大)进行排序,或者根据构造队列时提供的 Comparator 进行排序,具体取决于所使用的构造方法。
PriorityQueue 队列不允许放入 null,也不允许插入不可比较的对象(没有实现 Comparable 接口的对象)。
其实可以插入一个没有实现 Comparable 接口的对象,此时再进行插入就会出现:java.lang.ClassCastException: demos.other.MyNode cannot be cast to java.lang.Comparable
。
PriorityQueue 队头指排序规则最小的那个元素。如果多个元素都是最小值则随机选一个(待验证)。
部分源码如下:
public class PriorityQueue<E> extends AbstractQueue<E>
implements java.io.Serializable {
private static final long serialVersionUID = -7720805057305804111L;
private static final int DEFAULT_INITIAL_CAPACITY = 11;
transient Object[] queue;
// The number of elements in the priority queue.
private int size = 0;
// The comparator, or null if priority queue uses elements' natural ordering.
private final Comparator<? super E> comparator;
transient int modCount = 0;
public PriorityQueue() {
this(DEFAULT_INITIAL_CAPACITY, null);
}
public PriorityQueue(int initialCapacity) {
this(initialCapacity, null);
}
public PriorityQueue(Comparator<? super E> comparator) {
this(DEFAULT_INITIAL_CAPACITY, comparator);
}
public PriorityQueue(int initialCapacity,Comparator<? super E> comparator) {
// 实际上不需要至少有一个限制,但可以继续保持1.5的兼容性
if (initialCapacity < 1)
throw new IllegalArgumentException();
this.queue = new Object[initialCapacity];
this.comparator = comparator;
}
}
PriorityQueue 优先级规则可以根据具体需求而定制, 方式有 2 种:
- 添加元素自身实现 Comparable 接口,确保元素是可排序的对象。
- 添加元素没有实现 Comparable 接口,可以在创建 PriorityQueue 队列时直接指定比较器 Comparator。
构造队列时提供的 Comparator 示例
import java.util.Comparator;
import java.util.PriorityQueue;
public class PriorityQueueDemo {
public static void main(String[] args) {
Comparator<MyNode> comparator = new Comparator<MyNode>() {
@Override
public int compare(MyNode o1, MyNode o2) {
return o1.x - o2.x;
}
};
PriorityQueue<MyNode> queue = new PriorityQueue<>(comparator);
queue.offer(new MyNode(4));
queue.offer(new MyNode(8));
queue.offer(new MyNode(1));
queue.offer(new MyNode(5));
queue.offer(new MyNode(7));
queue.offer(new MyNode(2));
while (queue.size() != 0) {
System.out.println(queue.poll());
}
}
}
class MyNode {
int x;
MyNode(int x) {
this.x = x;
}
@Override
public String toString() {
return "MyNode:" + x;
}
}
输出:
MyNode:1
MyNode:2
MyNode:4
MyNode:5
MyNode:7
MyNode:8
可排序对象示例
import java.util.PriorityQueue;
public class PriorityQueueDemo {
public static void main(String[] args) {
PriorityQueue<MyComparableNode> queue = new PriorityQueue<>();
queue.offer(new MyComparableNode(4));
queue.offer(new MyComparableNode(8));
queue.offer(new MyComparableNode(1));
queue.offer(new MyComparableNode(5));
queue.offer(new MyComparableNode(7));
queue.offer(new MyComparableNode(2));
while (queue.size() != 0) {
System.out.println(queue.poll());
}
}
}
class MyComparableNode implements Comparable<MyComparableNode> {
int x;
MyComparableNode(int x) {
this.x = x;
}
@Override
public int compareTo(MyComparableNode o) {
return this.x - o.x;
}
@Override
public String toString() {
return "MyComparableNode:" + x;
}
}
输出:
MyComparableNode:1
MyComparableNode:2
MyComparableNode:4
MyComparableNode:5
MyComparableNode:7
MyComparableNode:8