本来想先看看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
有什么讨论的内容,可以加我公众号:
来源:oschina
链接:https://my.oschina.net/u/2277632/blog/2239745