将不可比较的对象添加到PriorityQueue

时间:2015-08-31 19:25:02

标签: java priority-queue

请考虑以下代码:

import java.util.PriorityQueue;

public class Test {

    public static void main(String argv[]) {
        PriorityQueue<A> queue = new PriorityQueue<>();
        System.out.println("Size of queue is " + queue.size()); // prints 0
        try {
            queue.add(new A());
        } catch (ClassCastException ignored) { }
        System.out.println("Size of queue is " + queue.size()); // prints 1
    }

} 
class A { } // non-comparable object

在此代码中,明确不具有可比性的对象将添加到PriorityQueue。按照PriorityQueue.add Javadoc的预期,此代码会抛出ClassCastException,因为该对象无法比较。

但是,虽然抛出了异常,但似乎队列的大小仍在增加。

我原本希望两个print语句输出0但第二个输出实际输出1,好像一个对象已被添加到队列中。

这里发生了什么?

3 个答案:

答案 0 :(得分:4)

我不希望在该行上抛出异常。更密切地阅读文档:可能会抛出异常

  

如果根据优先级队列的顺序无法将指定的元素与当前在此优先级队列中的元素进行比较

由于优先级队列中当前没有其他元素,因此我不一定会期望抛出异常。

答案 1 :(得分:4)

这是文档中的实际陈述:

  

依赖自然排序的优先级队列也不允许插入不可比较的对象(这样做可能会导致ClassCastException)。

对非允许的队列执行某些操作意味着无法保证队列在完成时的行为方式。作为额外的确认,请仔细查看此部分:“这样做可能会产生ClassCastException。”换句话说,甚至不需要实现抛出异常。

答案 2 :(得分:2)

您声称add()引发了异常,但您的测试并未证明该声明。如果实际上抛出了 异常,那么你应该期望队列的大小保持为0.但是,你不应该指望抛出异常。

PriorityQueue.add()的文档说:

  

ClassCastException - 如果指定的元素无法根据优先级队列的顺序与当前在此优先级队列中的元素进行比较

如果没有其他元素,则不会出现这种情况。但是,如果您尝试添加另一个元素,则应抛出异常,并且队列的大小应保持为1。