2009-02-13 105 views
2

我的大部分编程经验都是在一种语言中有一个集合数据结构 - 一个数组。现在我主要在.NET中工作,我已经开始欣赏可用的大量工具,但我也很难确定哪种工具最适合每个问题。我觉得这通常是收藏品的情况。System.Collections - 为什么有这么多选项?

我敢肯定,我将能够发现作业更快随时间/经验的正确工具,但任何人都可以提供一些指导其集合类是好的哪些工作?遵循什么好的经验法则?

编辑:我发现我几乎总是使用List(T),这就是引发这个问题的原因之一。我知道有非常具体的原因使用其他类。尽管List(T)工作的次数最多,但我希望避免在其他结构更适合时将某些内容干扰到通用列表中。我必须能够发现这些情况。

谢谢!

回答

15

你没有说你以前用什么语言,但我觉得说,如果你相信数组是唯一可用的东西,那么你可能错了相当有信心。例如,C++本身只支持数组“集合”(在这里非常松散地使用“集合”),但是通过添加指针,您可以实现.Net中可用的任何集合数据结构的等价物。事实上,如果您查看C++标准模板库,您会发现大多数常见结构的库存实现。

的原因的附加结构是数组并不总是,或甚至通常,最合适的结构,以用于数据的集合。它有许多限制,可以由一个集合或另一个待解决,并利用这些不同的集合,你可以经常得到大得多表现出来的少得多代码,并降低的机会有一个在你的数据结构实现中的错误以及。

当决定要使用哪种集合类型时,您需要看看它将如何使用最后的。例如,集合中的所有对象是否都具有相同的类型,是否继承了相同的类型或任何类型?你会经常添加和删除项目?如果是这样,你会一直推/弹出,队列/出列项目,还是你需要添加项目到特定的位置?你会通过键,索引还是两者查找特定项目?如果通过密钥,密钥是如何确定的?

一些常见的集合:

  • List<T>也许应该在的,你已经习惯了使用数组的情况下使用。它通过使用相同的语法与性能接近一个数组的数组索引支持查找,是强类型,并使其非常容易的添加或删除项目和非常快的追加或流行的项目(插入到特定的位置要慢得多)。如果你做任何正式的计算机科学培训

  • LinkedList<T>应该听起来很熟悉。它使用类似于List的语法,但是进行了不同的优化:查找速度较慢,因为它们需要遍历列表,而向特定位置添加或删除项目可能会更快。

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

  • SortedList<TKey, TValue>的工作原理与Dictionary类似,不同之处在于,当您迭代它时,项将返回按键排序。但是,如果没有首先迭代它之前的所有项目,就无法查找第n个项目。

  • KeyedCollection经常被忽略,因为它隐藏在与某些其他集合不同的名称空间中,并且必须实现一个(非常容易)的函数才能使用它。它也很像字典,除此之外它还支持通过索引轻松查找。当项目的键是项目本身的简单属性时,通常使用它。

  • 不要忘记旧的standbys:StackQueue。再一次,如果你有任何正式的计算机科学教育,你应该已经有一个很好的想法,这些工作是如何基于他们的名字。

最后,大多数这些集合(数组包括!)实现了一组通用接口。这些接口非常有用,因为您可以针对接口而不是特定的集合编写程序,然后您的功能可以接受实现该接口的任何集合。例如,下面的代码将工作,你是否在一个字符串数组传递,一个List<string>,或任何其他IEnumerable<string>

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

值得看的其他接口包括IList<T>ICollection<T>IQueryable<T>

+0

有些事情,你可能想要添加到你的回复很好:添加元素到列表只有在最后添加它们时才是快速的;并提及LinkedList ,它具有非常快速的插入和删除任何地方,但不直接支持索引元素。 – Thomas 2009-02-13 19:57:28

0

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

队列启用FIFO实现,无需您自己动手。堆栈给你LIFO。 SortedLists为您提供预分类列表等。

集合命名空间中还有许多其他的,并且全部讨论here

3

泛型列表(列表)很适合常用。他们不执行拳击和拆箱。所以没有performans问题。

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

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

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

SortedLists哈希表是存储键 - 值对。你可以为你的物品定义一个键。这有助于您快速找到它们。 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"); 

希望这有助于!

0

我可以提供的两个提示: 1.尽可能使用通用集合。 2.当在HashSet和List通用集合之间做出决定时,确实看看你将要使用它们。哈希集的搜索速度可能会更快,但插入速度也会减慢(我已经找到)。

0

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

1

就像在计算机科学中许多其他的事情,当有多个选择,它通常意味着有做事的多种方式。正如其他人所说,每个系列都有各种优点和缺点。不管您使用的是仿制药的收藏品与否,最终所有藏品提供这些操作:

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

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

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

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

因此取决于你的程序在做什么,大部分时间将决定使用哪个集合。

相关问题