首页 > 解决方案 > 具有内部比较器类的 PriorityQueue

问题描述

我尝试使用内部 Comparator 类以降序实现优先级队列,但是当我打印优先级队列时,我没有得到正确的结果。当我为 Collection.sort 尝试相同的比较器代码来实现列表的排序(具有相同的值)时。我得到了正确的结果。你能解释一下吗?

//int[] nums = {50,10, 20, 30, 40};
    public static void TestComparatorcomparemethod(int[] nums){
        PriorityQueue<Integer> pq= new PriorityQueue<>(nums.length,new Comparator<Integer>(){
            @Override
            public int compare(Integer o1,Integer o2){
                int a = (int)o1;
                int b = (int)o2;
                if (a > b)
                    return -1;
                else if (a==b)
                    return 0;
                else
                    return 1;
            }
        });
        for (int node:nums){
            pq.add(node);}
        System.out.println("pq values are " + pq);
}

上述代码的答案是 pq 值为 [50, 40, 20, 10, 30]

        List<Integer> al = new ArrayList<>();
        al.add(50);
        al.add(10);
        al.add(20);
        al.add(30);
        al.add(40);
        Collections.sort(al, new Comparator<Integer>(){
            @Override
            public int compare(Integer o1,Integer o2){
                int a = (int)o1;
                int b = (int)o2;
                if (a > b)
                    return -1;
                else if (a==b)
                    return 0;
                else
                    return 1;
            }
        } );
        System.out.println("The arraylist values are: " + al);

上面代码的答案是数组值是:[50, 40, 30, 20, 10]

标签: javacomparatorpriority-queue

解决方案


对于优先级队列,意外的顺序 [50, 40, 20, 10, 30]是可以的(预期的)。因为迭代优先级队列并不能保证排序顺序。但是,如果您使用 peek/poll,您将看到返回了预期值。

来自文档

此类及其迭代器实现了 Collection 和 Iterator 接口的所有可选方法。方法 iterator() 中提供的 Iterator 不能保证以任何特定顺序遍历优先级队列的元素。如果您需要有序遍历,请考虑使用Arrays.sort(pq.toArray())

您的比较器代码没问题。如果您确实需要按顺序打印值,请尝试:

 System.out.println("pq values are " + Arrays.sort(pq.toArray());

推荐阅读