为什么优先队列的元素默认按照自然顺序排序,因为它没有实现类似的接口。
从docs开始,它表示元素是根据自然顺序排序的,但我无法在任何地方找到有关equals方法的说法,也无法比较。它内部发生了什么?
所有已实现的接口:Serializable,Iterable,Collection,Queue。
如果它具有可比性,那么为什么它没有在上面的行中说明
示例:
public static void main(String[] args) {
PriorityQueue<String> pq = new PriorityQueue<String>();
pq.add("2");
pq.add("4");
System.out.println(pq); //prints [2, 4]
pq.offer("1");
System.out.println(pq); // prints [1, 4, 2]
pq.add("3");
System.out.println(pq); // prints [1, 3, 2, 4]
}
}
另外,第三个打印语句打印[1,3,2,4]而不是打印[1,2,3,4]。为什么?它应该是自然的顺序吗?
答案 0 :(得分:6)
实际上PriorityQueue
的内部数据结构没有排序,它是 heap 。
PriorityQueue
不需要订购,而是专注于头数据。插入位于 O(log n)时间。排序会浪费时间,对队列来说无用。
此外,元素是-a Comparable
或Comparator
。不幸的是,不可比较的检查是在运行时,而不是编译时。添加第二个元素后,会发生ClassCastException
。
加:我回答为什么[1,3,2,4]而不是打印[1,2,3,4] ?
正如我之前提到的,它没有被订购,相反它专注于头部q[0]
是最小的,那就是它。
你可以看到[1,3,2,4]是一个非线性的树:
1
| \
3 2
|
4
答案 1 :(得分:1)
优先级队列依赖于以下内容对元素进行排序:
答案 2 :(得分:0)
实际上,PriorityQueue只允许那些实现Comparable的元素,或者你需要提供Custom Comparator。
Comparator中允许使用Integer和String值,因为它们实现了Comparable接口。例如 public final class String实现java.io.Serializable,Comparable,CharSequence
public final class Integer extends Number实现Comparable
如果您创建自己的类,例如Employee,那么它应该实现Comparable,或者您应该提供自定义Comparator。
我希望这会解决您的疑问!!!!
答案 3 :(得分:0)
您看到的是该订单,因为:
1.内部System.out.println()将调用toString()方法,该方法又使用迭代器迭代队列的元素。但是迭代器不保证任何特定的顺序来遍历元素。请参阅此
http://docs.oracle.com/javase/6/docs/api/java/util/PriorityQueue.html
2。优先级队列基于优先级堆。在没有任何比较器的情况下插入元素时,优先级队列在内部使用siftUpComparable()方法。 siftUpComparable()将当前元素与其在堆中的父位置的元素进行比较。如果订单不正确,则交换当前元素和父元素。这样做直到当前元素和父元素的顺序正确。订购基于元素的自然顺序。
3。由于优先级队列基于优先级堆,因此它的主要焦点将放在队列前面的元素上。
因此,当元素使用poll()从队列中出队时,元素会被排序。这样做是为了提高优先级队列的性能。优先级队列仅在需要时对元素进行排序
如果您想将订单视为[1,2,3,4],请使用此
while(pq.size() != 0) {
System.out.println(pq.poll());
}