一、概念
1. 它是基于优先级堆的无界优先级队列;
2. 其元素是按照自然排序或者在队列构建时提供的方法来进行排序;
3. 队列中不允许存在null元素;
4. 它不是多线程安全的;
5. 它使用的是二叉堆,二叉堆分为大根堆和小根堆,大根堆是父节点的值总是大于或等于子节点的值,小根堆是父节点的值总是小于或等于子节点的值;
6. 它总是一棵完全而查实或近似完全二叉树;
7. 它内部的实现是基于数组格式的,对于数组中任意位置n上的元素,它的左孩子是在[2n+1]的位置上,它的右孩子是在[2n+2]的位置上,它的父节点则在[(n-1)/2]上,而根节点在[0]上;
二、PriorityQueue源码分析
1.初始化定义
在PriorityQueue中初始化定义了5个变量,可以看到它的底层存储逻辑是用数组实现的,默认的初始化容量是11.
//默认容量为11
private static final int DEFAULT_INITIAL_CAPACITY = 11;
//元素的存储方式是数组
private transient Object[] queue;
//队列中元素的个数
private int size = 0;
//比较器
private final Comparator<? super E> comparator;
//队列修改的次数
private transient int modCount = 0;
2.PriorityQueue的构造函数
PriorityQueue的构造函数有多种,比如下面代码中的前三种都是根据默认容量、默认比较器或者指定的容量或比较器来创建一个空的队列,而在后面几种方法中都是根据指定的集合创建包含指定元素的优先级队列:
(1)PriorytyQueue():创建一个默认容量(11)和自然顺序的优先级队列;
(2)PriorityQueue(int initialCapacity):创建一个指定容量和自然顺序的优先级队列;
(3)PriorityQueue(int initialCapacity,Comparator<? super E> comparator):创建一个指定容量和指定比较器的优先级队列;
(4)PriorityQueue(Collection<? extends E> c):创建一个包含指定集合元素的优先级队列,它分为三种情况:
第一种:如果是一个已经排好序的集合,首先根据集合获取到他的比较器方法,然后将集合中的元素添加到队列中;
第二种:如果是一个优先级队列,首先获取比较器方法,然后将指定优先级队列中的元素赋值到该队列中;
第三种:其他情况默认使用自然比较器,将集合中的元素添加到队列中;
(5)PriorityQueue(PriorityQueue<? extends E> c):创建一个包含指定优先级队列的队列,他的实现逻辑与(4)中的第二种情况相同;
(6)PriorityQueue(SortedSet<? extends E> c):创建一个包含指定排序集合中元素的优先级队列,他的实现逻辑与(4)中的第一种情况相同
/**
* 构造函数:创建一个默认容量(11)和自然顺序的PriorityQueue
*/
public PriorityQueue() {
this(DEFAULT_INITIAL_CAPACITY, null);
}
/**
* 构造函数:创建一个指定容量和自然顺序的队列
* @param initialCapacity
*/
public PriorityQueue(int initialCapacity) {
this(initialCapacity, null);
}
/**
* 构造函数:创建一个指定容量和指定顺序的队列
* @param initialCapacity
* @param comparator
*/
public PriorityQueue(int initialCapacity,
Comparator<? super E> comparator) {
if (initialCapacity < 1)
throw new IllegalArgumentException();
this.queue = new Object[initialCapacity];
this.comparator = comparator;
}
/**
* 构造函数:根据指定集合创建一个队列
* 如果c是有序的集合:根据集合获取到对应的比较器comparator,将集合中的元素
* @param c
*/
@SuppressWarnings("unchecked")
public Priority