为什么priorityQueue在编译时不需要类似的接口?

时间:2012-05-17 15:18:05

标签: java

以下代码对于传递编译是合法的。为什么可以将PriorityQueue定义为仅采用可比较的实例?

...
PriorityQueue<Object> q = new PriorityQueue<Object>();
q.add(new Object());
...

但它抛出了预期的例外:

Exception in thread "main" java.lang.ClassCastException: java.lang.Object cannot be cast     to java.lang.Comparable
    at java.util.PriorityQueue.siftUpComparable(PriorityQueue.java:595)
    at java.util.PriorityQueue.siftUp(PriorityQueue.java:591)
    at java.util.PriorityQueue.offer(PriorityQueue.java:291)
    at java.util.PriorityQueue.add(PriorityQueue.java:268)
    at ReentrantLockExample.main(ReentrantLockExample.java:12)

2 个答案:

答案 0 :(得分:5)

因为 允许您为不是Comparator的元素类型指定自己的Comparable。这也会影响TreeSetTreeMap以及基本上所有其他已排序的集合。

如果您在自己的代码中尝试避免使用它,请选择工厂方法来构造,因为您可以在不同的工厂方法上指定不同的类型约束。例如,Guava provides

<E extends Comparable> TreeSet<E> Sets.newTreeSet();
<E> TreeSet<E> Sets.newTreeSet(Comparator<? super E> comparator);

答案 1 :(得分:1)

只要您提供Comparable ,就可以存储未实现Comparator的对象。

来自documentation

  

优先级队列的元素按照其自然顺序排序,或者在队列构造时提供Comparator,具体取决于使用的构造函数。优先级队列不允许null个元素。依赖于自然排序的优先级队列也不允许插入不可比较的对象(这样做可能会导致ClassCastException)。