PriorityQueue可以自定义传入的Comparator来比较内部元素的大小,Comparator比较时的返回如下:
如果o1 == o2 ,返回0
如果o1 < o2 ,即 o1-o2 < 0 ,则返回负数
如果o1 > o2 ,即 o1-o2 > 0 ,则返回正数

如下是PriorityQueue类中新放入元素时执行的代码,x是新放入的元素,k是队列大小,这里只要关注x就好了。可以看到满足 comparator.compare(x, (E) e) >= 0 时会跳出循环,e是队列中原先就存在的元素,即输入的x停止继续往堆顶上升:
private void siftUpUsingComparator(int k, E x) {
while (k > 0) {
int parent = (k - 1) >>> 1;
Object e = queue[parent];
if (comparator.compare(x, (E) e) >= 0)
break;
queue[k] = e;
k = parent;
}
queue[k] = x;
}
所以当使用如下自定义比较器时,o1对应x(输入的元素),o2对应e(队列中原有的元素):
new PriorityQueue<>(k, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
})
此时如果o1-o2>=0,即x>=e时,x会停止往堆顶上升。否则如果o1-o2<0,即x<e时(即输入的元素值x会比较小),x会继续往堆顶上升,这样构建出来的就是最小堆,堆顶的元素值最小。
代码换一下,变成o2-o1。此时如果o2-o1>=0,即e>=x时,x会停止往堆顶上升。否则如果o2-o1>=0,即e<x时(即输入的元素值x会比较大),x会继续往堆顶上升,这样构建出来的就是最大堆,堆顶的元素值最大:
new PriorityQueue<>(k, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
})
总结下就是,比较器比较o1 和 o2时,如果o1比较大,o1比较大会停止继续往堆顶上升,此时就是最小堆;如果o1比较小,那就是最大堆。









![[XR-FRAME] 1.O4 文档导览 || XR-FRAME / 让场景更丰富,环境数据](https://img-blog.csdnimg.cn/54665ff58c814519883b18920a20e8f5.png)









