注意:这里讨论的是基于堆实现的优先级队列!java
基于java自带的PriorityQueue是一个能自动扩容的优先级队列,而lucene实现了一个可以维护固定尺寸的队列(只保留最大或最小的前N个数值)可是不能自动扩容。因而想象能着能不能将二者的优势结合,作一个既能自动扩容,又能维护固定尺寸的优先级队列。数组
实际上最后没能实现,缘由以下:队列
假设咱们的需求是从队列中获取最小的元素it
一、既然是获取最小的元素,那么该堆必定是个最小堆(即堆顶部的元素值最小);io
二、若是要保留最小的前N个数值,每次在插入新的元素时须要将队列中最大的元素给替换掉,所以咱们须要将堆变成一个最大堆(这样就与已是最小堆的状况造成了矛盾)!技巧
三、现假设队列能自动扩容,那么在插入的时候队列保留的是全部元素而不是前N个最小元素,所以又造成了矛盾。lucene
四、实际上lucene在实现的时候使用了一些小技巧:因为第1步咱们采用了最小堆,到第2步的时候与第1步产生了矛盾,因此咱们经过最小堆不能生成前N个最小的序列了。反过来咱们能够实现保留最大的前N个数值,由于每次插入新元素时只需将队列中最小的元素给替换掉!生成
注:lucene在实现堆的时候,数组下标是从1开始的(这是由于在计算父子节点的下标时能够少一些加法运算)。