为什么将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
答案 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的作者)知道更好:)