简体   繁体   English

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

[英]Why should I use Deque over Stack and LinkedList over Queue?

When I learn about Stack and Queue, It uses a stack/queue over an ArrayList.当我了解堆栈和队列时,它在 ArrayList 上使用堆栈/队列。 However, I search the API by Intellij, Stack and Queue use ArrayDeque class in a list collection, not ArrayList.但是,我通过 Intellij 搜索 API,Stack 和 Queue 在列表集合中使用 ArrayDeque 类,而不是 ArrayList。

  /**
  * <p>A more complete and consistent set of LIFO stack operations is
   * provided by the {@link Deque} interface and its implementations, which
  * should be used in preference to this class.  For example:
  * <pre>   {@code   *   Deque<Integer> stack = new ArrayDeque<Integer>();}
  */

In Queue, It uses LinkedList class in the LinkedList API.在 Queue 中,它使用 LinkedList API 中的 LinkedList 类。 and also Most people's codes like:以及大多数人的代码,例如:

Queue<Integer> q1 = new LinkedList<>()

/**
 * Queue operations.
 * Retrieves, but does not remove, the head (first element) of this list.
 *
 * @return the head of this list, or {@code null} if this list is empty
 * @since 1.5
 */

The point is, when it explains about the concept, Stack and Queue, use ArrayList.重点是,当它解释堆栈和队列的概念时,使用 ArrayList。

But, in reality, use LinkedList or ArrayDeque, not ArrayList.但是,实际上,使用 LinkedList 或 ArrayDeque,而不是 ArrayList。 Would you explain why?你会解释为什么吗?

Most of this question is specific to Java, but the part about using an array-list as a queue is more general.这个问题的大部分是特定于 Java 的,但关于使用数组列表作为队列的部分更通用。


In Java specifically, you should use an ArrayDeque or another deque implementation instead of the Stack class: according to the documentation,特别是在 Java 中,您应该使用ArrayDeque或其他双端队列实现而不是Stack类:根据文档,

A more complete and consistent set of LIFO stack operations is provided by the Deque interface and its implementations, which should be used in preference to this class. Deque 接口及其实现提供了一组更完整和一致的 LIFO 堆栈操作,应优先使用此类。

Another reason to prefer ArrayDeque for most use-cases is that Stack extendsVector , which is a synchronized implementation.在大多数用例中更喜欢ArrayDeque另一个原因是Stack扩展了Vector ,这是一个同步实现。 Synchronization has a performance penalty, and is unnecessary when the stack will only be accessed from a single thread (ie almost all of the time).同步有性能损失,当堆栈只能从单个线程访问时(即几乎所有时间),同步是不必要的。

An ArrayDeque is better than an ArrayList as a stack, because to simulate the pop method on an ArrayList you have to write s.remove(s.size() - 1) , which is inconvenient and less clear. ArrayDeque作为堆栈比ArrayList更好,因为要在ArrayList上模拟pop方法,您必须编写s.remove(s.size() - 1) ,这s.remove(s.size() - 1)方便又不太清楚。


The reason you should use a LinkedList "instead of" a Queue is because Queue is an interface, not a class, so you simply can't write new Queue<>() to create a queue;您应该使用LinkedList “而不是” Queue的原因是因为Queue是一个接口,而不是一个类,所以您根本无法编写new Queue<>()来创建队列; this will give a compilation error.这将产生编译错误。

Note that it's still best to declare the type of your variable as Queue<...> .请注意,最好将变量的类型声明为Queue<...>


The reason you shouldn't use an ArrayList as a queue is more general: it is a dynamic array data structure , so it only supports add and remove operations in O(1) time at one end.不应该使用ArrayList作为队列的原因更普遍:它是一种动态数组数据结构,因此它只支持在 O(1) 时间内的添加和删除操作。 Adding or removing at the other end takes O(n) time.在另一端添加或删除需要 O(n) 时间。 So it is unsuitable to use as a queue because a queue should enqueue and poll at different ends, and the operation at one end will be inefficient compared to other more suitable queue data structures.所以不适合作为队列使用,因为一个队列应该在不同的端入队和轮询,并且与其他更合适的队列数据结构相比,在一端的操作会效率低下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM