简介
优先队列PriorityQueue是Queue接口的实现,可以对其中元素进行排序,可以放基本数据类型的包装类(如:Integer,Long等)或自定义的类。对于基本数据类型的包装器类——>优先队列中元素默认排列顺序是升序排列;但对于自己定义的类来说——>需要自己定义比较器
遍历获取元素:类及其迭代器实现Collection和Iterator接口的所有可选方法。 方法iterator()中提供的迭代器不能保证以任何特定顺序遍历优先级队列的元素。 如果需要有序遍历,请考虑使用Arrays.sort(pq.toArray()) 。
多线程场景:请注意,此实现不同步。 如果任何线程修改队列,多线程不应同时访问PriorityQueue实例。 而是使用线程安全的PriorityBlockingQueue类。
在游乐园门口有很多人在排队进场,这就是一个`Queue`.这时暴发户小明想插队提前进场,`Queue`显然就不符合了,
因为`Queue`是严格按照`FIFO`原则取数据的.我们需要用优先队列`PriorityQueue`,`PriorityQueue`区别于`Queue`,
它取元素的顺序跟元素的优先级有关,每次取的都是队列中优先级最高的元素.
/** 版本号 */
private static final long serialVersionUID = -7720805057305804111L;
/** 默认初始容量 */
private static final int DEFAULT_INITIAL_CAPACITY = 11;
/** 核心数组 */
transient Object[] queue;
/** 元素数量 */
private int size = 0;
/** 比较器,如果当前使用元素自然排序,此变量为null */
private final Comparator<? super E> comparator;
/** 记录 涉及到结构变化的次数(offer/remove/clear等) */
transient int modCount = 0;
/** 数组的最大容量 尝试分配更大的数组可能会导致OutOfMemoryError:请求的数组大小超过VM限制 */
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
取出元素
删除元素
public boolean remove(Object o) {
int i = indexOf(o);
if (i == -1)
return false;
else {
removeAt(i);
return true;
}
}
remove(o)
函数删除指定元素,先根据indexOf
函数获取元素的下标.
private int indexOf(Object o) {
if (o != null) {
for (int i = 0; i < size; i++)
if (o.equals(queue[i]))
return i;
}
return -1;
}
indexOf
函数为直接遍历数组查找元素,再调用removeAt
函数删除元素.
private int indexOf(Object o) {
if (o != null) {
for (int i = 0; i < size; i++)
if (o.equals(queue[i]))
return i;
}
return -1;
}
private E removeAt(int i) {
modCount++;
int s = --size;
if (s == i) // 删除最后一个元素
queue[i] = null;
else {
E moved = (E) queue[s];
queue[s] = null;
// 向下调整
siftDown(i, moved);
if (queue[i] == moved) {
// queue[i] == moved 说明当前满足堆结构
// 需要向上调整
siftUp(i, moved);
if (queue[i] != moved)
// 返回moved 用于迭代器,本文不介绍.
return moved;
}
}
return null;
}