【问题标题】:Why should I use Deque over Stack and LinkedList over Queue?为什么我应该使用 Deque over Stack 和 LinkedList over Queue?
【发布时间】:2019-11-29 15:12:43
【问题描述】:

当我了解堆栈和队列时,它在 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>();}
  */

在队列中,它使用 LinkedList API 中的 LinkedList 类。 还有大多数人的代码,例如:

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
 */

重点是,在解释堆栈和队列的概念时,请使用 ArrayList。

但是,实际上,使用 LinkedList 或 ArrayDeque,而不是 ArrayList。 你能解释一下为什么吗?

【问题讨论】:

    标签: java data-structures linked-list stack queue


    【解决方案1】:

    这个问题大部分是针对 Java 的,但是关于使用数组列表作为队列的部分更为笼统。


    特别是在 Java 中,您应该使用 ArrayDeque 或其他双端队列实现而不是 Stack 类:根据文档,

    Deque 接口及其实现提供了一组更完整和一致的 LIFO 堆栈操作,应优先使用该类。

    在大多数用例中更喜欢ArrayDeque 的另一个原因是Stack 扩展了Vector,这是一个同步实现。同步有性能损失,当堆栈只能从单个线程访问时(即几乎所有时间),同步是不必要的。

    ArrayDeque 比 ArrayList 作为堆栈更好,因为要在 ArrayList 上模拟 pop 方法,您必须编写 s.remove(s.size() - 1),这很不方便且不太清晰。


    你应该使用LinkedList“而不是”Queue的原因是因为Queue是一个接口,而不是一个类,所以你根本不能写new Queue&lt;&gt;()来创建一个队列;这会产生编译错误。

    请注意,最好将变量的类型声明为Queue&lt;...&gt;。


    您不应该使用ArrayList 作为队列的原因更普遍:它是dynamic array data structure,因此它只支持在O(1) 时间内完成添加和删除操作。在另一端添加或删除需要 O(n) 时间。所以不适合作为队列使用,因为一个队列要在不同的端入队和轮询,而在一端的操作相对于其他更合适的队列数据结构效率会很低。

    【讨论】:

      猜你喜欢
      • 2011-01-15
      • 1970-01-01
      • 2010-11-08
      • 2020-08-03
      • 1970-01-01
      • 1970-01-01
      • 2015-07-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多