为什么ArrayDeque类不能从AbstractQueue扩展?

时间:2014-08-06 09:30:01

标签: java collections arraydeque

为什么将ArrayDeque类定义为

public class ArrayDeque<E> extends AbstractCollection<E>
                       implements Deque<E>, Cloneable, Serializable

而不是

public class ArrayDeque<E> extends AbstractQueue<E>
                       implements Deque<E>, Cloneable, Serializable

如果你看下面的图(有错误,ArrayDeque与Set的关系是完全错误的),那么ArrayDeque将继承AbstractQueue是有意义的,因为它通过Deque接口间接地实现了Queue接口。

http://en.academic.ru/pictures/enwiki/67/Collection_Classes.jpg

2 个答案:

答案 0 :(得分:1)

OpenJDK core-libs上发布了一个jsr166维护者:

  

我根本不认为ArrayDeque是队列/双端队列。我们只有两个   这里的基本数据结构(ArrayList(普通的可调整大小的数组)和   ArrayDeque(循环可调整大小的数组))两者都可以实现List和   以合理的方式排队,ArrayDeque可以另外实现Deque。

扩展AbstractCollection并实现Deque与该视图一致。

这也是一个保守的举动,因为it would allow future versions of ArrayDeque to extend AbstractList实现了大多数List接口。只有在由于equals / hashCode合约冲突而被认为是合法的或desirable to implement both List and Queue时才会发生这种情况。

答案 1 :(得分:0)

ArrayDeque可以用作双端队列,堆栈和链表。我认为这更像是一个设计决策。在这里,在ArrayDeque中,我们需要在添加/删除元素时更具体。例如。

[ArrayDeque.java]
    public boolean add(E e) {
        addLast(e);
        return true;
    }
[AbstractQueue.java]
public boolean add(E e) {
        if (offer(e))
            return true;
        else
            throw new IllegalStateException("Queue full");
    }

由于deque是双重结束,我们需要具体说明我们添加元素的位置。

另一个设计考虑因素可能是减少调用堆栈。如果继承AbstractQueue,它将增加函数调用堆栈而没有额外的好处。

例如,

现在,

add() - &gt; addlast仅()

如果它继承了AbstractQueue,

add() - &gt; offer() - &gt; offerLast() - &gt; addlast仅()

此外,通过不继承AbstractQueue,我们可以重用小块add,删除ArrayDeque中实现的不同数据结构(队列,堆栈和链接列表)的操作。

最后,Joshua Bloch(此API的作者)知道更好:)