首页 > 解决方案 > PriorityQueue 的顺序不对

问题描述

我在Java 8 Intellij Idea中遇到了关于PriorityQueue顺序的问题,当我在队列中添加第三个数字时,顺序是错误的,但只有第三个有这个问题,这是我的代码。

import java.util.*;

public class vector {
    static Queue<Integer> q=new PriorityQueue<Integer>();
    public static void addNum(int num) {
        q.add(num);
    }
    public static void main(String args[]) {
        addNum(-1);
        addNum(-2);
        addNum(-3);
        addNum(-4);
        addNum(-5);
    }
}

我尝试调试代码,在addNum(-3)之后,队列是-3,-1,-2,但是在addNum(-4)之后,队列是-4,-3,-2,-1。

标签: javapriority-queue

解决方案


for 的契约PriorityQueue不保证迭代顺序,而是保证从优先级队列中删除的每个元素都将遵循队列类型的自然排序,或者如果提供了自定义比较器的排序。

Javadoc对您所看到的内容进行了评论:

队列通常但不一定以 FIFO(先进先出)方式对元素进行排序。例外情况包括优先级队列,它根据提供的比较器或元素的自然顺序对元素进行排序,以及对元素进行排序的 LIFO 队列(或堆栈) LIFO(后进先出)。

Java 似乎对优先级队列强制执行的约定是,从队列中删除的第一个元素将遵循队列中对象的自然顺序,或者使用自定义比较器,如果提供的话。

如果我们添加到您当前的脚本以删除添加的五个元素,我们将看到返回的项目将从最小到最大排序:

public static void main(String args[]) {
    addNum(-1);
    addNum(-2);
    addNum(-3);
    addNum(-4);
    addNum(-5);

    // now remove all elements
    while (!q.isEmpty()) {
        System.out.println(q.remove());
    }
}

这打印:

-5
-4
-3
-2
-1

如果您需要一个保持排序顺序的集合,请考虑使用类似TreeSet. 或者,您可以使用常规ArrayList,然后Collections.sort()在您想强制执行某个命令时调用。


推荐阅读