正如评论中已经提到的,我们有经过良好测试的Deque
界面,应该是首选。
但我会告诉你为什么Stack
不应该使用的原因。
首先,Java Doc。堆栈的自己说:
Deque 接口及其实现提供了一组更完整和一致的 LIFO 堆栈操作,应优先使用此类。例如:
Deque<Integer> stack = new ArrayDeque<Integer>();
请参阅JavaDoc。
那么Stack
班级的问题是什么。
就像 Martin Fowler 在他的书Refactoring: Improvement the Design of Existing Code中已经提到
的重构方法Replace Inheritance with Delegation一样,Stack 不应该从 Vector 继承。
不恰当继承的典型例子之一是使堆栈成为向量的子类。Java 1.1 在其实用程序中做到了这一点(顽皮的男孩!)[6, p. 288]
相反,他们应该使用如下图所示的委托,这也来自书中。
参见这里:用委托替换继承

那么,为什么这是一个问题:
因为堆栈只有 5 个方法:
- 流行音乐
- 推
- 是空的
- 搜索
- 尺寸
size()
并且isEmpty()
是从类继承的,并且不使用Vector
其他方法。Vector
但是通过继承,其他方法被转发给Stack
没有意义的类。
福勒对这个问题说:
您可以接受这种情况并使用约定说虽然它是一个子类,但它只使用了超类函数的一部分。但这会导致代码在您的意图是另一件事时说一件事——您应该消除这种混乱。
这损害了接口隔离原则
其中说:
不应强迫客户依赖他们不使用的接口。
您可以查看Vector和Stack类的源代码,您会看到 Stack 类继承了该类的spliterator
方法和VectorSpliterator
innerClass Vector
。
这个方法被Collection
接口用来实现。流方法的默认版本:
default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}
因此,请避免简单地使用Vector
andStack
类。
[6] 重构:改进现有代码的设计 Fowler,Martin 1997 年