无法理解PriorityQueue如何更改排序顺序?

时间:2017-06-01 07:24:11

标签: java collections

import java.util.*;
class abc {

    public static void main(String args[]){

        PriorityQueue<Integer> pq = new PriorityQueue<Integer>();

        pq.add(1);
        pq.add(2);
        pq.add(3);
        pq.add(4);
        pq.add(5);
        pq.add(6);

        System.out.println(pq);
        pq.remove();
        System.out.println(pq);     
    }           
}

删除元素后,请更改订单。 根据词典排序,输出应按升序排列。但我得到输出:

output

3 个答案:

答案 0 :(得分:3)

致电System.out.println(pq);与致电System.out.println(pq.toString());

相同

如果您查看documentation of the the toString() method,您会看到它声明:

  

返回此集合的字符串表示形式。字符串   表示由一系列集合中的元素组成   它们由迭代器返回,括在方括号中   (&#34; []&#34)。相邻元素由字符&#34;,&#34;分隔。 (逗号   和空间)。元素将转换为字符串   将String.valueOf(对象)。

我强调了重要的部分。所以我们需要看一下documentation of the iterator of the priority queue所说的内容:

  

返回此队列中元素的迭代器。 迭代器   不按任何特定顺序返回元素。

因此,代码的输出不允许对优先级队列强加的顺序作出任何结论。

main documentation of the PriorityQueue中说:

  

不保证方法iterator()中提供的迭代器   以任何特定顺序遍历优先级队列的元素。   如果您需要有序遍历,请考虑使用   Arrays.sort(pq.toArray())。

答案 1 :(得分:3)

PriorityQueue实现了一个Heap数据结构。此数据结构具有保持元素部分排序的属性。堆是一个二叉树(即使在实践中它是在数组中实现的),它保持以下不变性:如果节点P有子C,则P的值小于/大于C的值。

因此,只保证第一个元素(根)是集合的最小值/最大值,而所有其他值只是部分排序。

为什么这样?好吧,如果你必须保留一个完整的排序集合,插入/删除操作将采用O(n),而使用堆数据结构时,它们都是O(log n)。如果您只对集合的最大/最小值感兴趣,那么PriorityQueue与完成的排序数组相比具有明显的优势。

答案 2 :(得分:1)

来自AbstractCollectiontoString()方法的文档(当您将队列传递给System.out.println()方法时调用):

  

字符串表示由一个集合列表组成   元素按其迭代器返回的顺序,[...]

来自PriorityQueue iterator()方法的文档:

  

返回此队列中元素的迭代器。迭代器的确如此   不按任何特定顺序返回元素

你的答案就在那里。