添加不可比较的对象时,PriorityQueue的大小会增加

Tun*_*aki 6 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
        queue.add(new A()); // does not throw an exception
        try {
            queue.add(new A()); // this time, an exception is thrown
        } catch (ClassCastException ignored) {
            System.out.println("An exception was thrown");
        }
        System.out.println("Size of queue is " + queue.size()); // prints 2
    }

} 

class A { } // non-comparable object
Run Code Online (Sandbox Code Playgroud)

在此代码中,首先将不可比较的对象添加到a PriorityQueue.这段代码工作得很好,如前所述.

然后,将第二个对象添加到此队列.按照PriorityQueue.addJavadoc的预期,ClassCastException抛出a 是因为第二个对象与第一个对象不可比.

但是,尽管抛出了异常,但似乎队列的大小增加了:第二个print语句输出2而不是1.

这种行为有望吗?如果是这样,这背后的原因是什么?它在哪里记录?

spe*_*bob 9

根据GrepCode.com的源版本,看起来它可能是它们实现中的一个错误.

所有添加功能都是调用

public boolean add(E e) {
    return offer(e);
}
Run Code Online (Sandbox Code Playgroud)

offer函数看起来像这样

public boolean offer(E e) {
    if (e == null)
        throw new NullPointerException();
    modCount++;
    int i = size;
    if (i >= queue.length)
        grow(i + 1);
    size = i + 1;
    if (i == 0)
        queue[0] = e;
    else
        siftUp(i, e);
    return true;
}
Run Code Online (Sandbox Code Playgroud)

您会注意到在通过siftUp实际插入项目之前调用size = i + 1.当调用siftUp时,它首先要做的是尝试强制转换为Comparable并在实际插入项之前抛出异常.因此,它增加大小而不实际插入项目.