文章目录
- PriorityQueue基础知识
- 概述
- PriorityQueue内部结构
- PriorityQueue扩容操作
- PriorityQueue队列的构造方法
- PriorityQueue队列的常用方法
- public boolean offer(E e)
- public E peek()
- public boolean remove(Object o)
- public boolean contains(Object o)
- public Object[] toArray()
- public int size()
- public void clear()
- public E poll()
PriorityQueue基础知识
概述
PriorityQueue继承至AbstractQueue,并实现了java.io.Serializable接口:
public class PriorityQueue<E> extends AbstractQueue<E>
implements java.io.Serializable
PriorityQueue内部结构
PriorityQueue队列为了保证读 / 写性能的平衡,始终维持着一个堆结构,它保证了在每次添加新数据对象、移除已有数据对象后,集合都能维持小顶堆的特点。也就是说,PriorityQueue队列每进行一次写操作,都会针对集合中新的数据情况进行调整,保证部集合中所有数据对象始终按照小顶堆或大顶堆的结构特点进行排序。
PriorityQueue队列内部使用一个数组变量queue存储数据对象:
/**
* Priority queue represented as a balanced binary heap: the two
* children of queue[n] are queue[2*n+1] and queue[2*(n+1)]. The
* priority queue is ordered by comparator, or by the elements'
* natural ordering, if comparator is null: For each node n in the
* heap and each descendant d of n, n <= d. The element with the
* lowest value is in queue[0], assuming the queue is nonempty.
*/
transient Object[] queue; // non-private to simplify nested class access
PriorityQueue扩容操作
PriorityQueue队列的默认初始容量大小为11:
private static final int DEFAULT_INITIAL_CAPACITY = 11;
当数组容量达到上限时,需要进行扩容操作。
扩容操作实现如下:
private void grow(int minCapacity) {
int oldCapacity = queue.length;
// Double size if small; else grow by 50%
int newCapacity = oldCapacity + ((oldCapacity < 64) ?
(oldCapacity + 2) :
(oldCapacity >> 1));
// overflow-conscious code
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
queue = Arrays.copyOf(queue, newCapacity);
}
当PriorityQueue队列的原始容量值小于64时,进行双倍扩容;原始容量值大于64时,进行50%扩容。
最大允许分配容量为:
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
PriorityQueue队列的构造方法
1. 创建一个初始容量为11的PriorityQueue队列
public PriorityQueue() {
this(DEFAULT_INITIAL_CAPACITY, null);
}
2. 创建一个具有指定初始容量的PriorityQueue
public PriorityQueue(int initialCapacity) {
this(initialCapacity, null);
}
3. 构造一个包含指定集合元素的PriorityQueue
public PriorityQueue(Collection<? extends E> c) {
if (c instanceof SortedSet<?>) {
SortedSet<? extends E> ss = (SortedSet<? extends E>) c;
this.comparator = (Comparator<? super E>) ss.comparator();
initElementsFromCollection(ss);
} else if (c instanceof PriorityQueue<?>) {
PriorityQueue<? extends E> pq = (PriorityQueue<? extends E>) c;
this.comparator = (Comparator<? super E>) pq.comparator();
initFromPriorityQueue(pq);
} else {
this.comparator = null;
initFromCollection(c);
}
}
4. 创建包含 PriorityQueue队列中的元素的PriorityQueue
public PriorityQueue(PriorityQueue<? extends E> c) {
this.comparator = (Comparator<? super E>) c.comparator();
initFromPriorityQueue(c);
}
5. 创建默认初始容量为DEFAULT_INITIAL_CAPACITY的 PriorityQueue ,并根据指定的比较器对其元素进行排序
public PriorityQueue(Comparator<? super E> comparator) {
this(DEFAULT_INITIAL_CAPACITY, comparator);
}
6. 创建具有默认初始容量的 PriorityQueue ,并根据指定的比较器对其元素进行排序
public PriorityQueue(int initialCapacity,
Comparator<? super E> comparator) {
// Note: This restriction of at least one is not actually needed,
// but continues for 1.5 compatibility
if (initialCapacity < 1)
throw new IllegalArgumentException();
this.queue = new Object[initialCapacity];
this.comparator = comparator;
}
PriorityQueue队列的常用方法
public boolean offer(E e)
将指定的元素插入到此PriorityQueue队列中。
public boolean offer(E e) {
if (e == null)
throw new NullPointerException();
modCount++;
int i = size;
if (i >= queue.length)
grow(i + 1);
size = i + 1;
if (i == 0)
queue[0] = e;
else
siftUp(i, e);
return true;
}
public E peek()
检索但不删除此队列的头部,如果此队列为空,则返回 null 。
public E peek() {
return (size == 0) ? null : (E) queue[0];
}
public boolean remove(Object o)
删除指定对象元素,删除成功返回true。
public boolean remove(Object o) {
int i = indexOf(o);
if (i == -1)
return false;
else {
removeAt(i);
return true;
}
}
public boolean contains(Object o)
如果此队列包含指定的元素,则返回true 。
public boolean contains(Object o) {
return indexOf(o) != -1;
}
public Object[] toArray()
返回一个包含此队列中所有元素的数组。
public Object[] toArray() {
return Arrays.copyOf(queue, size);
}
public int size()
返回此集合中的元素数。
public int size() {
return size;
}
public void clear()
清空
public void clear() {
modCount++;
for (int i = 0; i < size; i++)
queue[i] = null;
size = 0;
}
public E poll()
检索并删除此队列的头,如果此队列为空,则返回 null 。
public E poll() {
if (size == 0)
return null;
int s = --size;
modCount++;
E result = (E) queue[0];
E x = (E) queue[s];
queue[s] = null;
if (s != 0)
siftDown(0, x);
return result;
}