.net 为什么要使用Stack< T>而不是List< T>?

jvidinwx  于 2023-01-31  发布在  .NET
关注(0)|答案(6)|浏览(150)

List<T> from System.Collections.Generic执行Stack<T>执行的所有操作,甚至更多--它们基于相同的底层数据结构。在什么情况下选择Stack<T>是正确的?

unguejic

unguejic1#

如果你需要一个后进先出的项目集合,你可以使用stack.一个列表允许你在任何索引访问它的项目.还有很多其他的区别,但我想说这是最基本的.
发表评论后更新:
我想说,使用Stack<T>表明了您希望如何使用此代码,为将来做计划总是好的,但是如果您现在需要Stack<T>,并且没有令人信服的理由使用List<T>,那么我会选择Stack<T>

0s7z1bwu

0s7z1bwu2#

为什么我会限制自己在新代码中使用Stack
答案就在这里--当您需要强制执行一个契约期望,即所使用的数据结构只能作为一个堆栈来操作时,您应该使用Stack。当然,您真正希望这样做的次数是有限的,但在适当的时候,它是一个重要的工具。
例如,假设要处理的数据没有任何意义,除非强制堆栈顺序。在这种情况下,如果将数据作为列表提供,则会给自己带来麻烦。通过使用Stack(或Queue,或任何其他顺序敏感的结构),您可以在代码中准确地指定数据的使用方式。

2w2cym1i

2w2cym1i3#

如果你想在逻辑上表示一个栈,你可能会想使用Stack,如果你使用栈,它将在整个代码中传达程序员的意图,并且它将防止对数据结构的无意误用(无意中添加/删除/阅读一端以外的地方)。
当然,Stack可能只是一个接口,而不是一个具体的实现。然后,您可以使用List之类的东西来实现该接口。问题主要是方便性问题。如果有人需要堆栈,他们需要选择一些特定的实现并记住(“哦,是的,List是首选的堆栈实现”),而不是仅仅更新具体的类型。

vvppvyoh

vvppvyoh4#

这都是关于概念的,List是List,Stack是Stack,它们做的是两件非常不同的事情,它们唯一的共同点是它们的通用性和可变长度。
List是一个可变尺子的项目集合,其中的任何元素都可以通过索引访问和覆盖,并且可以在任何这样的索引处向其添加项目和从中删除项目。
栈是支持LIFO存取模型的可变长度的项集合;只有栈的顶部元素可以被访问,并且元素只能被添加到集合的那个“端点”和从集合的那个“端点”移除。来自“顶部”的项3元素只能通过“弹出”它上面的两个元素来暴露它来访问。
使用正确的作业工具;当你需要“随机”访问集合中的任何元素时,使用List。当你想强制对数组中的元素进行更有限的“仅顶层”访问时,使用Stack。当你想强制FIFO“管道”时,使用Queue。物品从一端进,从另一端出。

uttx8gqw

uttx8gqw5#

除了概念上的不同之外,正如其他答案已经指出的那样,Stack中还有不同的方法,在使用List时,这些方法使您的代码比对应的代码更干净(更容易)。
例如,使用Stack时的简单对象池代码段:

if (!pool.TryPop(out var obj))
{
    obj = new Foo();
}

并且在保持操作O(1)的同时将其写为List

Foo obj;
int count = pool.Count;
if (count > 0)
{
    obj = pool[--count];
    pool.RemoveAt(count);
}
else
{
    obj = new Foo();
}
d8tt03nd

d8tt03nd6#

System.Collections.Generic.Stack<T>是一种LIFO(后进先出)数据结构 * 也称为 * stack
尽管名称如此,SCG.List<T>并不是抽象数据类型[linked] list:它实际上是variable-length array
两种截然不同的生物。

相关问题