CH22-PriorityQueue
PriorityQueue(优先级队列)是一种在队列的基础上支持优先级的,PriorityQueue的优先级表现为一个PriorityQueue会关联一个Comparator,Comparator的结果体现了优先级的大小。PriorityQueue内部使用了数组来保存元素,支持动态扩容,整个数组会当做一个堆,每次加入删除元素的时候会调整堆。
PriorityQueue构造器
public PriorityQueue() {
this(DEFAULT_INITIAL_CAPACITY, null);
}
public PriorityQueue(int initialCapacity) {
this(initialCapacity, null);
}
public PriorityQueue(int initialCapacity) {
this(initialCapacity, null);
}
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;
}
默认的初始容量为11,如果没有提供自己的Comparator,那么会默认认为PriorityQueue的泛型类实现了Comparable接口. 初始容量为11? 也不知道怎么想的。
PriorityQueue的增加,删除,获取元素
public boolean add(E e) {
return offer(e);
}
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;
}
PriorityQueue的动态增长策略是:
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);
}
原长度小于64,就每次只加2,大于64之后,就在原来的基础上增加1.5倍。what the hell… PriorityQueue底层的数组,每次在插入,移除某个元素时都需要重新调整堆:
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;
}
private void siftDown(int k, E x) {
if (comparator != null)
siftDownUsingComparator(k, x);
else
siftDownComparable(k, x);
}
@SuppressWarnings("unchecked")
private void siftDownComparable(int k, E x) {
Comparable<? super E> key = (Comparable<? super E>)x;
int half = size >>> 1; // loop while a non-leaf
while (k < half) {
int child = (k << 1) + 1; // assume left child is least
Object c = queue[child];
int right = child + 1;
if (right < size &&
((Comparable<? super E>) c).compareTo((E) queue[right]) > 0)
c = queue[child = right];
if (key.compareTo((E) c) <= 0)
break;
queue[k] = c;
k = child;
}
queue[k] = key;
}
这种堆在优先级上来说,是最大堆,数组的0位置元素是最优先的,这个最优先的元素在Comparator比较小,具有最小的值,这种越小的值越优先的策略可以理解为对弱者的一种重视.
Others
PriorityQueue这种基于堆的结构,在插入和删除是都非常高效,O(logn)。PriorityQueue也支持序列化。提供了readObject和writeObject方法,这两个方法在ObjectInputStream和ObjectOutputStream时都会调用.
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.