学习PriorityQueue源码

本来想先看看DelayQueue,结果里面用到了PriorityQueue,所以先学习一下PriorityQueue的编码逻辑。

学习PriorityQueue源码基于优先级堆的无界优先级队列。优先级队列的元素根据其自然顺序排序,或者由队列构造时提供的比较器排序,具体取决于使用的构造函数。优先级队列不允许null元素。依赖于自然排序的优先级队列也不允许插入不可比较的对象(这样做可能导致ClassCastException)。

此队列的头部是指定排序的最小元素。如果多个元素被绑定为最小值,则头部是这些元素之一。

PriorityQueue是无限制的,但具有内部容量,用于控制用于存储队列中元素的数组的大小。它始终至少与队列大小一样大。当元素添加到优先级队列时,其容量会自动增加。

PriorityQueue不是线程安全的,所以多线程操作的时候要注意一下。

学习PriorityQueue源码

我们可以看到PriorityQueue的构造方法比较多,我们看一下比较有特点的,下面是赋值一个initialCapacity和比较器comparator的,如果没有初始化,那么会使用默认值DEFAULT_INITIAL_CAPACITY = 11

学习PriorityQueue源码

还有对于集合的构造函数,这里对SortedSet和PriorityQueue特殊处理了一下,获取comparator,但是还是有PriorityQueue(PriorityQueue<? extends E> c)和PriorityQueue(SortedSet<? extends E> c)两个构造函数,对于其他集合,是不会设置comparator。最终大家的归宿都是调用initElementsFromCollection,initFromPriorityQueue和initFromCollection。

学习PriorityQueue源码

以上三个方法都是赋值this.queue和this.size,然后调用heapify构建堆,其中 >>> 是无符号右移,然后操作siftDown操作。

学习PriorityQueue源码

这个操作会根据有没有comparator,执行siftDownUsingComparator或者siftDownComparable。

学习PriorityQueue源码

等我梳理一些这个集合操作后,再慢慢看看这些构建的操作。

peek()操作获取堆的头部信息

学习PriorityQueue源码

offer​(E e):将指定的元素插入此队列,会先判断入参是否为null,然后判断数组大小是否足够,否则执行grow(int minCapacity)扩容,除非是第一个元素,否则会执行入堆的操作!

学习PriorityQueue源码

poll​():检索并删除此队列的头部,如果此队列为空,则返回null。然后执行siftDown操作。

学习PriorityQueue源码

remove​(Object o):从此队列中删除指定元素的单个实例(如果存在)。

学习PriorityQueue源码

这次看的有点粗糙,我们后续再补充!

下节再续!

参考:https://docs.oracle.com/javase/9/docs/api/java/util/PriorityQueue.html

有什么讨论的内容,可以加我公众号:

学习PriorityQueue源码