从源码看PriorityQueue
add/offer
java.util.PriorityQueue#add
将指定元素插入此优先级队列。
返回:true (由Collection.add指定)
抛出:ClassCastException – 如果根据优先级队列的顺序无法将指定元素与当前在此优先级队列中的元素进行比较
NullPointerException – 如果指定的元素为空
1 | // java.util.PriorityQueue#add |
进入offer -> siftUp,直接看siftUp函数
siftUp
java.util.PriorityQueue#siftUp
在位置 k 处插入项 x,通过将 x 向上提升树直到它大于或等于其父项或者是根来保持堆不变。 简化和加速强制和比较。 Comparable 和 Comparator 版本被分成不同的方法,这些方法在其他方面是相同的。 (类似于 siftDown。)
参数:k - 要填补的位置
x - 要插入的项目
1 | // java.util.PriorityQueue#siftUp |
这里根据有无比较器再分为两个情况,无比较器时使用自然顺序排序(Comparable natural ordering):
siftUpComparable
1 | private void siftUpComparable(int k, E x) { |
看这段代码,可以判断这里是一个小顶堆,每次元素进来,就和父节点比较([parent = (k - 1) >>> 1]这里可以找到父节点,(当前节点-1)/2),如果父节点大于新加节点,则交换值,然后再和父节点的父节点比较,以此类推。
poll
1 | // java.util.PriorityQueue#poll |
同理,出元素跟入的逻辑流程差不多,我们直接来到siftDown
->siftDownComparable
:
1 | private void siftDownComparable(int k, E x) { |
这里把最后一个元素拿出来,重建小顶堆。
从源码看PriorityQueue