概要
PriorityQueue是一个重要数据结构,是DelayQueue的底层实现,为例如任务调度的实现提供底层的数据结构。
PriorityQueue原理分析
如果你了解堆排序的话,它的实现对你而言就显得很简单。
先看看PriorityQueue有什么属性
1 | /** |
主要属性有 queue 一个数组,Comparator 比较器。
添加元素的 add/offer 方法:
1 | /** |
加入元素,grow是扩容,元素的插入主要看siftUp。
先看看grow方法:
1 | /** |
奇怪的 grow,就如注释所说的,小于 64 时扩容 2 倍,大于 64 时扩容 50%。
siftUp方法:
1 | /** |
siftUp 方法,为什么叫 up 呢,因为插入的位置是数组的最后,也就是二叉树的最后一个节点,所以要向上调整,这里就涉及堆排序的调整。
comparator 为空时,用 compareTo 比较,直到 parent 比插入的元素大,否则交换,就是这么简单。
取出元素的poll方法:
1 | public E poll() { |
取出元素,然后把最后的元素放在第一个的位置,然后调整,本质也是涉及堆排序的调整。
总结
利用堆排序实现插入、取出等操作时的重排序,目的是效率较高(我一开始认为是一个线性 array,然后通过 shift - 类似插入排序的样子,但是想想这是个 O(n) 的操作,堆排序是 O(logn)快多了);
默认实现是最小堆,当然也可以传入相反比较结果的 Comparator 实现最大堆;
没有传入 Comparator 的话,默认使用元素的 compareTo 方法,所以元素要是 Comparable 的,不然会报错;
全程没有锁,不支持高并发,不过有PriorityBlockingQueue;
不允许null元素;