学习PriorityQueue源码

天涯浪子 提交于 2019-12-05 01:32:51

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

下节再续!

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

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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!