首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么我应该使用Deque而不是Stack?

为什么我应该使用Deque而不是Stack?
EN

Stack Overflow用户
提问于 2012-09-21 13:38:05
回答 6查看 95.5K关注 0票数 206

我的用例需要一个Stack数据结构。我应该能够将项推送到数据结构中,并且我只想从Stack中检索最后一项。JavaDoc for Stack说:

Deque接口及其实现提供了一组更完整和一致的后进先出堆栈操作,应该优先于此类使用。例如:

代码语言:javascript
复制
Deque<Integer> stack = new ArrayDeque<>();

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

附言:来自Deque的javadoc说:

后进先出(

Deques )也可用作后进先出( LIFO )堆栈。应该优先使用此接口,而不是传统的Stack类。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2012-09-21 13:49:35

首先,它在继承方面更明智。在我看来,Stack扩展Vector的事实真的很奇怪。在Java早期,继承被过度使用了,IMO - Properties就是另一个例子。

对我来说,你引用的文档中的关键字是一致的。Deque公开了一组操作,这些操作都是为了能够从集合的开头或结尾获取/添加/删除项,迭代等-仅此而已。故意不能通过位置来访问元素,因为Stack公开了位置,因为它是Vector的子类。

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

同样,正如评论中指出的那样,StackDeque具有反向迭代顺序:

代码语言:javascript
复制
Stack<Integer> stack = new Stack<>();
stack.push(1);
stack.push(2);
stack.push(3);
System.out.println(new ArrayList<>(stack)); // prints 1, 2, 3


Deque<Integer> deque = new ArrayDeque<>();
deque.push(1);
deque.push(2);
deque.push(3);
System.out.println(new ArrayList<>(deque)); // prints 3, 2, 1

Deque.iterator()的JavaDocs中也解释了这一点

以正确的顺序返回此双队列中的元素的迭代器。元素将按从第一个(头部)到最后一个(尾部)的顺序返回。

票数 243
EN

Stack Overflow用户

发布于 2020-04-22 13:11:54

以下是Deque比Stack更好的几个原因:

面向对象的设计-继承、抽象、类和接口: Stack是一个类,Deque是一个接口。只能扩展一个类,而Java中的单个类可以实现任意数量的接口(类型的多重继承)。使用Deque接口消除了对具体Stack类及其祖先的依赖,并为您提供了更大的灵活性,例如,可以自由扩展不同的类或换出Deque的不同实现(如LinkedList、ArrayDeque)。

不一致: Stack扩展了Vector类,允许您按索引访问元素。这与Stack实际应该做的事情不一致,这就是为什么首选Deque接口(它不允许这样的操作)--它允许的操作与FIFO或LIFO数据结构应该允许的操作一致。

性能: Stack扩展的Vector类基本上是ArrayList的“线程安全”版本。同步可能会对您的应用程序造成严重的性能影响。此外,使用不需要的功能扩展其他类(如#2所述)会使您的对象膨胀,可能会消耗大量额外的内存和性能开销。

票数 21
EN

Stack Overflow用户

发布于 2019-02-05 22:28:30

Stack上使用Deque的另一个原因是,Deque能够使用streams转换为列表,并保持后进先出的概念,而Stack不能。

代码语言:javascript
复制
Stack<Integer> stack = new Stack<>();
Deque<Integer> deque = new ArrayDeque<>();

stack.push(1);//1 is the top
deque.push(1)//1 is the top
stack.push(2);//2 is the top
deque.push(2);//2 is the top

List<Integer> list1 = stack.stream().collect(Collectors.toList());//[1,2]

List<Integer> list2 = deque.stream().collect(Collectors.toList());//[2,1]
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12524826

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档