java 队列和堆栈
我最近一直在研究一些需要堆栈和队列的Java代码。 使用的选择不是立即显而易见的。 有一个Queue接口,但没有明确的具体实现要使用。 还有一个Stack类,但是javadocs指出其他类“应该优先于此类使用”。 那么,您对Java中的堆栈和队列使用哪种实现?
我发现我的经验法则是可以将ArrayDeque类同时用于Stack和Queues,但下面提供了更多详细信息。
通用定义
首先,让我们从一些定义开始。 在该词的常用用法中,队列是FIFO(先进先出)。 就像在邮局排队的第一个人一样。 堆栈为LIFO(后进先出)。 想象一堆书–您放在书堆中的最后一本书是您摘下的第一本书。
Java中的选择
在Java中,情况稍微复杂一些,但原理相同。 有前面提到的Queue接口,该接口具有添加,删除和查看元素的预期方法。 (实际上,这些方法有两种形式:一种在操作失败时引发异常,另一种返回特殊值,例如null或false;请参见此处 )。
还有一个名为Deque的Queue子接口,它是“双头队列”的缩写,通常发音为“ deck”。 该接口定义访问集合两端的元素的方法。 此功能使Deque成为队列和堆栈实现的有用基础。
但是,Queue和Deque都是接口,因此我们仍然没有找到要使用的具体实现…
候选清单:ArrayDeque和LinkedList
2个主要选择是: ArrayDeque和LinkedList 。 Deque还有其他一些实现,例如ConcurrentLinkedDeque和LinkedBlockingDeque,以及大量的Queue实现,例如DelayQueue,LinkedBlockingDeque和PriorityQueue。 由于这些功能较为专业(而且我使用的并不多),因此我不再赘述。
ArrayDeque
从javadocs开始 ,ArrayDeque是Deque接口的可调整大小的数组实现。 除remove *,contains *和bulk操作外,大多数ArrayDeque操作均以摊销的固定时间运行(即“偶尔”,但平均为常数),所有操作均以线性时间运行。 文档指出,此类用作堆栈时,可能比Stack快,而用作队列时,则比LinkedList快。 这条语句使我使用ArrayDeque作为堆栈和队列的默认实现。
链表
LinkedList类实现List,Queue和Deque接口。 除了实现List接口之外,LinkedList类还提供统一命名的方法,以获取,删除和在列表的开头和结尾插入元素。 这些操作允许将链接列表用作堆栈,队列或双端队列。
LinkedList与ArrayDeque
因此,何时使用ArrayDeque上的LinkedList?
LinkedList实现的优点是:
- 比ArrayDeque实现更灵活,因为它
- 实现所有可选的列表操作。
- 非常适合需要频繁删除/插入列表中间的项目(某些情况可能会导致ArrayDeque的大型数组副本)。
LinkedList实现的缺点:
- 一般而言,在迭代项目时并不理想
- 比ArrayDeque实现消耗更多的内存
总体
在效率方面,ArrayDeque比LinkedList在两端进行迭代和添加/删除操作效率更高。 因此,正如javadocs所指出的那样,通常,在用作堆栈时,ArrayDeque可能比堆栈快,而当用作队列时,则比LinkedList快。
翻译自: https://www.javacodegeeks.com/2013/10/stacks-and-queues-in-java.html
java 队列和堆栈