什么时候使用List和LinkedList更好?
当前回答
将链表视为列表可能会有一些误导。它更像一个链条。事实上,在。net中,LinkedList<T>甚至没有实现IList<T>。在链表中没有真正的索引概念,即使看起来有。当然,类中提供的方法都不接受索引。
链表可以是单链,也可以是双链。这是指链中的每个元素是否只与下一个元素有链接(单链),还是与前一个/下一个元素都有链接(双链)。LinkedList<T>是双重链接。
在内部,List<T>由一个数组支持。这在内存中提供了一个非常紧凑的表示。相反,LinkedList<T>涉及额外的内存来存储连续元素之间的双向链接。因此LinkedList<T>的内存占用通常会比List<T>的内存占用大(需要注意的是,List<T>可以有未使用的内部数组元素,以提高追加操作期间的性能)。
它们也有不同的表现特征:
附加
LinkedList<T>.AddLast(item)常量时间 List<T>.Add(item)平摊常数时间,线性最坏情况
预谋
LinkedList<T>.AddFirst(item)常量时间 列表> < T。插入(0,项)线性时间
插入
LinkedList < T >。AddBefore(节点,项目)常量时间 LinkedList < T >。AddAfter(节点,项目)常量时间 列表> < T。插入(索引、项)线性时间
删除
删除(项目)线性时间 删除(节点)常量时间 列表<T>.删除(项目)线性时间 List<T>.RemoveAt(index)线性时间
数
LinkedList < T >。计算常数时间 列表> < T。计算常数时间
包含
包含(项目)线性时间 列表<T>.包含(项)线性时间
清晰的
LinkedList<T>.Clear()线性时间 List<T>.Clear()线性时间
如你所见,它们基本上是相等的。实际上,LinkedList<T>的API使用起来更麻烦,其内部需求的细节会泄漏到代码中。
然而,如果你需要在一个列表中做很多插入/删除,它提供了常数时间。List<T>提供线性时间,因为列表中的额外项必须在插入/删除之后重新排列。
其他回答
在. net中,列表被表示为数组。因此,与LinkedList相比,使用普通List会更快。这就是为什么上面的人看到他们看到的结果。
Why should you use the List? I would say it depends. List creates 4 elements if you don't have any specified. The moment you exceed this limit, it copies stuff to a new array, leaving the old one in the hands of the garbage collector. It then doubles the size. In this case, it creates a new array with 8 elements. Imagine having a list with 1 million elements, and you add 1 more. It will essentially create a whole new array with double the size you need. The new array would be with 2Mil capacity however, you only needed 1Mil and 1. Essentially leaving stuff behind in GEN2 for the garbage collector and so on. So it can actually end up being a huge bottleneck. You should be careful about that.
当您需要内置索引访问、排序(以及二进制搜索之后)和“ToArray()”方法时,您应该使用List。
链表相对于数组的主要优点是,链接为我们提供了有效地重新排列项的能力。 塞奇威克,第91页
我问了一个类似的关于LinkedList集合性能的问题,发现Steven Cleary的Deque c#实现是一个解决方案。与Queue集合不同,Deque允许前后移动项目。它类似于链表,但性能有所改进。
使用LinkedList的常见情况是这样的:
假设您想要从一个字符串列表中删除许多特定的字符串,这些字符串的大小很大,比如100,000。要删除的字符串可以在HashSet dic中查找,字符串列表中应该包含30,000到60,000个这样的需要删除的字符串。
那么用于存储100,000个字符串的列表的最佳类型是什么?答案是LinkedList。如果它们存储在数组列表中,则遍历它并删除匹配的字符串将占用 到数十亿次操作,而使用迭代器和remove()方法只需要大约100,000次操作。
LinkedList<String> strings = readStrings();
HashSet<String> dic = readDic();
Iterator<String> iterator = strings.iterator();
while (iterator.hasNext()){
String string = iterator.next();
if (dic.contains(string))
iterator.remove();
}
推荐文章
- 如何在c#中获得正确的时间戳
- Linq选择列表中存在的对象(A,B,C)
- c# .NET中的App.config是什么?如何使用它?
- set()是如何实现的?
- c#:如何获得一个字符串的第一个字符?
- String类中的什么方法只返回前N个字符?
- 我如何提高ASP。NET MVC应用程序性能?
- 更好的方法将对象转换为int类型
- 我可以将c#字符串值转换为转义字符串文字吗?
- 在c#中转换char到int
- c#中朋友的对等物是什么?
- 关键字使用virtual+override vs. new
- 无法解析类型为“Microsoft.AspNetCore.Http.IHttpContextAccessor”的服务
- 在ASP中选择Tag Helper。NET Core MVC
- 如何在没有任何错误或警告的情况下找到构建失败的原因