C#集合集?

Oma*_*eji 463 .net c# collections set

有谁知道Set在C#中是否有与Java 集合相当的好处?我知道你可以使用a Dictionary或者HashTable通过填充而忽略值来模仿一个集合,但这不是一个非常优雅的方式.

Jon*_*eet 406

如果您使用的是.NET 3.5,则可以使用HashSet<T>.确实,.NET不像Java那样适应集合.

Wintellect的PowerCollections可以帮助太大.

  • @Louis:你在说什么?对于各种情况,Java有很多不同的Set实现..NET在.NET 3.5(HashSet)中有一个,在.NET 4中有两个(HashSet和SortedSet).我们不得不等到.NET 3.5开始的事实是非常令人惊讶的. (33认同)
  • 调用HashSet而不仅仅是Set的原因与Java中的相同 - "Set"描述了一个接口,而"HashSet"描述了一个实现 - 具体来说,这是一个由Hash Map支持的Set.通过这种方式,我们知道(或者应该强烈期望)插入和访问应该花费O(1)访问时间,相对于"LinkedListSet",这将导致我们期望插入和访问花费O(n)时间. (27认同)
  • 我怀疑Set是某些语言中的关键字,这可能会导致问题. (16认同)
  • `Set`是VB中的关键字. (5认同)
  • 你的意思是".NET不像Java那样适应集合."?与Java相比,这个Set在某种程度上是不完美的吗? (5认同)
  • @Manish:不,不是.请参阅C#3规范的第2.4.3节.它只对属性有特殊意义. (3认同)
  • 有谁知道为什么它被称为HashSet而不仅仅是Set? (2认同)

las*_*iya 121

HashSet<T>数据结构:

Framework Class Library的HashSet<T>数据结构是在.NET Framework 3.5中引入的.可以在MSDN参考页面HashSet<T>上找到其成员的完整列表.

HashSet<T>数学集之后或多或少地建模,这意味着:

  1. 它可能不包含重复值.

  2. 它的要素没有特别的顺序; 因此类型不实现IList<T>接口,但更基本ICollection<T>.因此,哈希集内的元素不能通过索引随机访问; 它们只能通过枚举器进行迭代.

  3. 某些设置功能,如Union,Intersection,IsSubsetOf,IsSupersetOf可供选择.当使用多组时,这些可以派上用场.

HashSet<T>和之间的另一个区别List<T>是调用哈希集的Add(item)方法返回一个布尔值:true如果项目已添加,false否则(因为它已在集合中找到).

为什么不List<T>呢?

由于a HashSet<T>只是一组唯一对象,您可能想知道为什么它必须是一个数据结构.List<T>通过检查在添加对象之前是否在列表中找到对象,法线可以具有相同的行为.

简短的回答是速度.List<T>随着更多元素的添加,正常搜索变得非常慢.A HashSet<T>需要一种结构设计,以便快速搜索和插入速度.

基准:

让我们比较a HashSet<T>和a 的性能速度List<T>.

每个试验包括向每个集合添加0到9,999的整数.但是,mod 25适用于每个整数.Mod 25生成最大类型的项目25.由于添加了10,000个元素,因此强制发生400次冲突,使数据结构有机会使用其搜索算法.在10,000次试验后测量3次并取平均值.

不要过多关注测试的具体运行时间,因为它们依赖于我的硬件,但看看它们是如何相互比较的.

           Average time [ms]
----------------------------
HashSet<T>             2,290
List<T>                5,505
Run Code Online (Sandbox Code Playgroud)

现在让我们创建元素对象而不是基本类型.我写了一个快速Person类有三个字段:Name,LastName,和ID.由于我没有包含任何比较对象的特定方法,因此将添加所有元素而不会发生冲突.这次Person为每次试验添加了1,000个对象进行单次试验.平均每组3次1,000次试验的总次数.

           Average time [ms]
----------------------------
HashSet<Person>          201
List<Person>           3,000
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,运行时间的差异在使用物体时变得天文数字,使其变得HashSet<T>有利.

  • 不会有9975次碰撞而不是400次碰撞吗? (13认同)

Lea*_*ash 120

试试HashSet:

HashSet(Of T)类提供高性能的集合操作.集合是一个不包含重复元素的集合,其元素没有特定的顺序......

HashSet(Of T)对象的容量是对象可以容纳的元素数.当元素添加到对象时,HashSet(Of T)对象的容量会自动增加.

HashSet(Of T)类基于数学集的模型,并提供类似于访问Dictionary(Of TKey,TValue)Hashtable集合的键的高性能集合操作.简单来说,HashSet(Of T)类可以被认为是没有值的Dictionary(Of TKey,TValue)集合.

HashSet(Of T)集合未排序,不能包含重复元素...

  • 不幸的是,直到最近才添加HashSets.如果您正在使用旧版本的框架,那么您将不得不坚持使用您的Munged Dictionary <>或Hashtable. (6认同)

Der*_*k W 20

如果您使用的是.NET 4.0或更高版本:

在您需要排序然后使用的情况下SortedSet<T>.否则,如果不这样做,则使用,HashSet<T>因为它O(1)用于搜索和操作操作.虽然SortedSet<T>O(log n)搜索和处理操作.


Chr*_*nal 14

我使用Iesi.Collections http://www.codeproject.com/KB/recipes/sets.aspx

它在许多OSS项目中使用,我首先在NHibernate中遇到它


the*_*oop 12

我在a周围使用了一个包装器Dictionary<T, object>,在值中存储空值.这使得O(1)在键上添加,查找和删除,并且所有意图和目的都像集合一样.

  • 你必须意味着它大致相当于std :: unordered_set.std :: set是有序的.例如,您可以快速找到范围的起点和终点,并从开始到结束迭代,按键顺序访问项目.SortedDictionary*大致相当于std :: set. (2认同)

dpa*_*pan 11

在CodePlex上查看PowerCollections.除了Set和OrderedSet之外,它还有一些其他有用的集合类型,如Deque,MultiDictionary,Bag,OrderedBag,OrderedDictionary和OrderedMultiDictionary.

对于更多集合,还有C5通用集合库.