System.Collections - 为什么这么多选项?

时间:2009-02-13 18:34:37

标签: .net arrays collections list

我的大多数编程经验都是使用一种语言,其中有一个集合数据结构 - 一个数组。现在我主要在.NET工作,我开始欣赏可用的大量工具,但我也发现很难确定哪种工具最适合每个问题。我发现这通常是收藏品的情况。

我确信我能够根据时间/经验更快地找到合适的工具,但是有人可以提供一些关于哪些收集类适合哪些工作的指导?有任何好的经验法则可以遵循吗?

编辑:我发现我几乎总是使用List(T),这就是提出这个问题的原因。我知道使用其他类有非常具体的原因。尽管List(T)工作时间最多,但我希望避免在其他结构更适合时将某些东西堵塞到通用列表中。我必须能够发现这些案件。

谢谢!

7 个答案:

答案 0 :(得分:15)

你没有说过你以前用过的语言,但我觉得如果你认为阵列是唯一可用的,那么你可能会错了。

例如,C ++本身仅支持数组“集合”(这里非常松散地使用“集合”),但是通过添加指针,您可以为.Net中可用的任何集合数据结构实现等效。实际上,如果你查看C ++标准模板库,你会发现大多数常见结构的库存实现。

附加结构的原因是数组并不总是,或者甚至经常是用于数据集合的最合适的结构。它有许多限制,可以通过一个或另一个集合来解决,使用这些不同的集合,您通常可以从更少的代码中获得更高的性能,并减少您的数据结构实施中也存在错误的可能性。

在决定使用哪种集合类型时,您需要查看它将如何使用大多数。例如,集合中的所有对象是否应该是相同类型,继承自相同类型或任何类型?您是否经常添加和删除项目?如果是这样,您是否总是推送/弹出,排队/出列项目或是否需要将项目添加到特定位置?您会按键,索引还是两者查找特定项目?如果按键,键是如何确定的?

一些更常见的集合:

  • List<T>应该用于大多数的习惯使用数组的情况。它支持使用与数组相同的语法查找索引,其性能接近于数组,是强类型的,并使非常易于添加或删除项目,并且非常快速地追加或弹出项目(插入特定位置要慢得多)。

  • 如果您已完成任何正式的计算机科学培训,
  • LinkedList<T>应该听起来很熟悉。它使用类似于List的语法,但进行了不同的优化:查找速度较慢,因为它们需要遍历列表,而将项目添加或删除到特定位置的速度要快得多。

  • Dictionary<TKey, TValue>使用类似于List<T>的语法,但您不是使用数组索引,而是将键值放在括号中。字典很棒,因为按密钥查找特定项目被认为是非常快,因为无论字典中有多少项目,它总是花费大约相同的时间来找到你的需要。

  • SortedList<TKey, TValue>的工作原理与字典类似,但有一点例外,当您迭代它时,按键排序的项目将返回。但是,如果没有先迭代它之前的所有项目,则无法查找第n个项目。

  • KeyedCollection经常被忽略,因为它隐藏在与其他一些集合不同的命名空间中,你必须实现一个(非常简单的)函数来使用它。它也像字典一样工作,另外它支持通过索引轻松查找。当项目的关键字是项目本身的简单属性时,通常使用它。

  • 不要忘记旧的备用证:StackQueue。同样,如果你有任何正式的计算机科学教育,你应该已经很清楚这些工作是如何根据他们的名字进行的。

最后,大多数这些集合(包括数组!)实现了一组通用接口。这些接口非常有用,因为您可以针对接口而不是特定集合编写程序,然后您的函数可以接受实现该接口的任何集合。例如,无论您是传入字符串数组,List<string>还是其他任何IEnumerable<string>,以下代码都将有效:

void WriteToConsole(IEnumerable<string> items)
{
    foreach (string item in items)
    {
       Console.WriteLine(item);
    }
}

值得关注的其他界面包括IList<T>ICollection<T>IQueryable<T>

答案 1 :(得分:3)

通用列表(列表)适合常用。他们不执行装箱和拆箱。所以没有表现出来的问题。

List<string> items = new List<string>();
items.Add("abc");
items.Add("dfg");

ArrayLists 接受任何对象作为项目。所以它们适合存储多种类型的情况。例如,如果你需要在同一个集合中存储一个int和一个字符串,那么arraylist对此很有用。

ArrayList items = new ArrayList();
items.Add("abc");
items.Add(1);
items.Add(DateTime.Now);

SortedLists Hashtables 是商店键值对。您可以为商品定义一个键。这有助于您快速找到它们。 SortedLists自动排序Hastables。

Hashtable items1 = new Hashtable();
items1.Add("item1", "abc");
items1.Add("item2", "dfg");

SortedList items2 = new SortedList();
items2.Add("Second", "dfg");
items2.Add("First", "abc");

希望这有帮助!

答案 2 :(得分:1)

与计算机科学中的许多其他事物一样,当有多种选择时,通常意味着有多种方法可以做某事。正如其他人所说,每个系列都有各种优缺点。无论您是否使用集合的通用版本,最终所有集合都提供以下操作:

  • 插入
  • 更新
  • 删除
  • 查找
  • 枚举

不同的集合对于每个操作都具有不同的性能特征。例如,数组可以快速更新项目,但插入或删除项目需要更长的时间。查找非常快。

将其与List进行比较。列表插入速度非常快。查找需要更长时间。更新和删除操作要求您已经拥有该项目并且非常快。数组和List的枚举大致相同。

所有集合也有某些行为,例如,集合是否保持排序。如果是这样,那么插入/更新/删除操作将花费更长时间,但会加快查找速度。

因此,根据您的程序正在执行的操作,大多数情况下将确定要使用的集合。

答案 3 :(得分:0)

Stacks,Queues,SortedList,Dictionary,HashTable等集合都是标准数据结构,在各种情况下派上用场。

队列启用FIFO实现,无需您自己完成。堆栈给你LIFO。 SortedLists为您提供预先排序的列表,依此类推。

集合名称空间中还有许多其他内容,并且都讨论了here

答案 4 :(得分:0)

我可以提供的两个提示: 1.尽可能使用通用集合。 2.在HashSet和List泛型集合之间进行决策时,请真正了解您将使用它们的内容。 Hashsets在搜索时可能会更快,但插入速度也会变慢(我已找到)。

答案 5 :(得分:0)

算法和数据结构。每一个都有其优点和缺点,每一个都有其目的。

答案 6 :(得分:0)

有很多与此问题相关的帖子,您必须考虑您真正需要做什么。你需要一个基于字符串的密钥(¿)如何填充数据,你需要一个本地方法来查找是否存在任何密钥,或者是否存在任何值(?)

泛型是我最常用的,但其他人有理由;)

http://discuss.fogcreek.com/dotnetquestions/default.asp?cmd=show&ixPost=5119