为什么我应该使用Deque over Stack?

我需要一个Stack结构为我的用例。 我应该能够将项目推入数据结构,我只想从堆栈中检索最后一个项目。 JavaDoc for Stack说:

Deque接口及其实现提供了更完整和一致的LIFO堆栈操作集,应优先使用这个类。 例如:

 Deque<Integer> stack = new ArrayDeque<>(); 

我绝对不希望同步行为在这里,因为我将这个数据结构本地使用的方法。 除此之外,为什么我更喜欢Deque over Stack

PS:来自Deque的javadoc说:

Deques也可以用作LIFO(后进先出)堆栈。 这个接口应该优先于传统的Stack类来使用。

一方面,从inheritance的angular度来看更为明智。 在我看来, Stack扩展Vector的事实真的很奇怪。 在Java早期,inheritance被过度使用IMO – Properties是另一个例子。

对我而言,你引用的文档中的关键词是一致的Deque公开了一组操作,这些操作都是关于能够从集合的开始或结束获取/添加/移除项目,迭代等 – 就是这样。 有意无意地按位置访问一个元素,这个Stack暴露, 因为它是Vector的一个子类。

哦,而且Stack也没有接口,所以如果你知道你需要Stack操作,你最终会提交一个特定的具体类,这通常不是一个好主意。

这里是我对堆栈类描述中提到的不一致的解释。

如果您在这里查看通用实现,您会发现实现集合,映射和列表的方法是一致的。

  • 对于设置和映射,我们有2个标准的哈希映射和树的实现。 第一个是最常用的,第二个是我们需要一个有序的结构(也实现了自己的接口 – SortedSet或SortedMap)。

  • 我们可以使用像Set<String> set = new HashSet<String>();的声明的首选样式Set<String> set = new HashSet<String>(); 看到这里的原因。

但是Stack类:1)没有自己的接口; 2)是Vector类的一个子类 – 它基于可resize的数组; 那么链表的实现栈在哪里呢?

在Deque接口中,我们没有这样的问题,包括两个实现(可resize的数组 – ArrayDeque;链表 – LinkedList)。

Deque是用来从头部和尾部检索元素的情况。 如果你想要一个简单的堆栈,没有必要去一个双动力。