【问题标题】:Java Collections (LIFO Structure)Java 集合(LIFO 结构)
【发布时间】:2010-09-23 01:55:54
【问题描述】:

我正在 Java 的 Collections 框架中寻找 LIFO 结构(堆栈),但没有成功。基本上我想要一个非常简单的堆栈;我的完美选择是 Deque,但我使用的是 Java 1.5。

我不想在我的结构中添加另一个类,但我想知道这是否可能:

  1. Collections 框架 (1.5) 中是否有任何类可以完成这项工作?

  2. 如果没有,有没有办法在不重新实现的情况下将队列转入 LIFO 队列(又名堆栈)?

  3. 如果不是,我应该为此任务扩展哪个接口或类?我想保持 Sun 的人在 Deque 上的做法是一个好的开始。

非常感谢。

编辑:我忘了说 Stack 类:当我看到它实现了 Vector 类时,我对这个类产生了怀疑,而且 Vector 类有点过时了,不是吗?

【问题讨论】:

  • Vector 的主要问题是所有访问都是同步的,无论您是否需要。它与任何其他集合一样“最新”,但由于同步问题而名声不佳。

标签: java collections stack queue


【解决方案1】:

实际上有一个 Stack 类:http://java.sun.com/j2se/1.5.0/docs/api/java/util/Stack.html

如果您不想使用它,LinkedList 类 (http://java.sun.com/j2se/1.5.0/docs/api/java/util/LinkedList.html) 具有 addFirstaddLastremoveFirstremoveLast 方法,非常适合用作堆栈或队列类.

【讨论】:

  • LinkedList 还提供了 Deque 的定义,这是您想要的集合。
  • 是的,我认为 LinkedList 是我一直在寻找的,因为在我第一次看到它时,我没有意识到 Addfirst 和 removeFirst 方法。非常感谢。
  • @SpencerKormos ... 和LinkedListArrayDeque 相比也支持空元素。
  • 更新这个答案现在已经过时了。 Stack 类已被更现代的类所取代,如 Javadoc 中所述:Deque 接口及其实现提供了一组更完整和一致的 LIFO 堆栈操作,应优先使用它类。Answer by Brett RyanAnswer by Ivan 中查看当前解决方案。
【解决方案2】:

我意识到我在这里聚会迟到了,但是 java.util.Collections (Java 7) 有一个静态的“asLifoQueue”,它接受一个 Deque 参数并返回(显然)双端队列的 LIFO 队列视图。我不确定这是添加了什么版本。

http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#asLifoQueue(java.util.Deque)

【讨论】:

    【解决方案3】:

    Deque, ArrayDeque, & LinkedList

    虽然之前有人问过这个问题,但提供一个 JDK6+ 答案可能是明智的,它现在提供了一个由ArrayDeque 数据结构实现的Deque(甲板)接口,并且更新了LinkedList 以实现这个界面。

    ConcurrentLinkedDeque & LinkedBlockingDeque

    并发访问的特殊形式也存在,由ConcurrentLinkedDequeLinkedBlockingDeque实现。

    LIFO 与 FIFO

    deque 的一大优点是它同时提供 LIFO(堆栈)和 FIFO(队列)支持,这可能会导致混淆哪些方法用于队列操作,哪些方法用于新人的堆栈操作。

    恕我直言,JDK 应该有一个Stack 接口和一个Queue 接口,它们仍然可以由ArrayDeque 之类的实现,但只公开该结构所需的方法子集,即后进先出可以定义@987654336 @、push()peek(),然后在上下文中

    LIFO<String> stack = new ArrayDeque<>();
    

    只有堆栈操作会被公开,以防止有人在打算使用 push(E) 时意外调用 add(E)

    【讨论】:

      【解决方案4】:

      Stack 类很慢:方法是同步的 + Stack 扩展同步 Vector

      【讨论】:

        【解决方案5】:

        有一个Stack class in the API。这能满足您的需求吗?

        【讨论】:

        • 对不起,我忘了说堆栈类和我对它的看法,但我认为这可能是比实现我自己的类更好的解决方案。不是吗?
        • 不要使用 Stack 类。它扩展了 Vector,保留它只是为了向后兼容。
        【解决方案6】:

        Deque & LinkedList

        为了完整起见,我提供了一个使用Deque 接口和LinkedList 实现的示例。

            Deque<String> deque = new LinkedList<>();
            deque.add("first");
            deque.add("last");
        
            // returns "last" without removing it
            System.out.println(deque.peekLast());
        
            // removes and returns "last"
            System.out.println(deque.pollLast());
        

        LinkedList 备份Deque 对性能很有好处,因为插入和删除元素是在恒定时间内完成的 (O(1))。

        单独使用LinkedList

            LinkedList<String> list = new LinkedList<>();
            list.add("first");
            list.add("last");
        
            // returns "last" without removing it
            System.out.println(list.getLast());
        
            // removes and returns "last"
            System.out.println(list.removeLast());
        

        【讨论】:

        • 原始帖子使用的队列显然是 FIFO 而不是 LIFO,所以我更新了答案。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-05-17
        • 2012-03-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-22
        相关资源
        最近更新 更多