Java LinkedList与Stack
在java中,可以使用LinkedList实现的堆栈。换句话说,您可以使用linkedlist来实现堆栈的所有功能。从这个意义上讲,为什么我们仍然需要堆栈类,为什么我们不坚持使用链表来保持简单性呢?Java LinkedList与Stack,java,linked-list,stack,Java,Linked List,Stack,在java中,可以使用LinkedList实现的堆栈。换句话说,您可以使用linkedlist来实现堆栈的所有功能。从这个意义上讲,为什么我们仍然需要堆栈类,为什么我们不坚持使用链表来保持简单性呢? 感谢您当您可以使用范围更窄或更正确的数据结构时,使用一个数据结构是有问题的,原因有两个: 更适合的数据结构可能会针对其拥有的操作子集或特定操作进行更优化(例如,假设您的应用程序需要一个列表,并且它基本上只在列表中间插入数据,您可能需要考虑链接列表与数组列表、相同操作,但是LinkedList更适合插
感谢您当您可以使用范围更窄或更正确的数据结构时,使用一个数据结构是有问题的,原因有两个:
另一方面,Java中更现代的堆栈实现是Java.util.Deque。首先,在
stack
的文档介绍中指出:
Deque
接口及其实现提供了一组更完整、更一致的后进先出堆栈操作,应优先于此类使用
这告诉我们,Stack
类主要是一个遗留类,它在较新的Java集合框架中或多或少变得多余
第二,“提供相同的功能”不是衡量类是否应该存在的好方法。虽然
LinkedList
提供了生成堆栈所需的所有操作,但它的性能很差。链表有利于在随机位置插入和删除元素。在堆栈中,我们只会在生成的末尾追加或删除元素>ArrayList
实现堆栈更具吸引力
此时,我们意识到ArrayList
和LinkdList
都提供了List
的功能,这使我们更接近良好的面向对象设计的核心:
- 我们在接口中定义一组操作(例如
)List
- 我们提供该接口的一个或多个实现,这些实现都必须提供所需的功能,但可以针对特定用例进行优化(例如
或ArrayList
)LinkedList
- 如果某个使用模式出现得特别频繁,我们可能会决定添加另一个在其名称中引用此模式的类,这将使代码结构更为完善。例如,我们可以通过简单地委托给
来实现ArrayList
,但提供一个在其名称中明确说明其含义的类型并且不提供可能违反堆栈概念的操作(如随机访问)。(这不是Stack
所做的,这让我们回到了文档中的引用。)java.util.stack
List
和较新的Deque
接口之间的继承关系比List
和Stack
之间的继承关系更为一致,LinkedList实现了Deque
,这是正确的,因为Deque
要求可以从开头或结尾添加和删除元素end和LinkedList
通过在随机位置提供插入和删除来满足这一要求。另一方面Stack
实现了List
,这应该被认为是有问题的
最新更新:由于我对“链表有利于在任意位置插入和删除元素。在堆栈中,我们只会在末尾追加或删除元素,这使得
ArrayList
实现堆栈更具吸引力”的说法投了赞成票,因此我想对此进行扩展
链表允许在固定时间内在任意位置插入和删除元素。另一方面,给定元素的索引,查找元素需要线性时间。当我说链表适合在随机位置插入和删除元素时,我指的是迭代器给定的位置,而不是索引。如果给定索引,则插入和删除对于链表和数组,n都是线性时间运算,但链表的常数因子要高得多
基于数组的列表允许在末尾进行分期固定时间插入和删除,以及按索引进行固定时间访问。在随机位置添加和删除元素是一个线性时间操作,无论位置是由索引还是由迭代器(基本上只是数组的索引)给出的
在堆栈实现中,链表的唯一优点是能够在任意位置插入和删除元素(由迭代器给出)在恒定时间内–是不需要的。另一方面,它的内存开销要高得多,并且它的内存访问大大低于连续数组的内存访问。考虑到在这两种情况下,从列表末尾追加和删除项的渐进复杂性都是摊销常数,因此基于数组的列表是i实现堆栈的存储
更好的数据结构应该是可变数量的固定大小的缓冲区,通过指针链接在一起。这种数据结构通常用于实现所谓的deque。它提供了数组的最大优点,只需很少的额外开销,以及从末尾(或开头)添加和删除不仅是一个摊销操作,而且始终是一个常数时间操作。堆栈类扩展了
向量
,因此它是同步的。链接列表
类是n