2008-10-08 58 views
397

有没有人知道在C#中是否有与Java的Set集合相当的好?我知道你可以使用DictionaryHashTable通过填充但忽略这些值来模仿一组数据,但这不是一个很好的方法。C#设置集合?

+0

你可以在这里找到一些关于Hashset的基本信息。 http://dotnetk.com/c-hashset-csharp/ – 2017-10-08 11:53:50

回答

55

尝试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)已收集没有排序,不能包含重复的元素......

+5

不幸的是,直到最近才添加了HashSets。如果您使用的是旧版本的框架,那么您将不得不坚持使用旧的Dictionary <>或Hashtable。 – 2008-10-08 16:36:48

388

如果您使用.NET 3.5,您可以使用HashSet<T>。确实,.NET并不像Java那样迎合集合。

Wintellect PowerCollections也可能有帮助。

+2

有没有人知道它为什么叫做HashSet而不是Set? – Wouter 2009-06-24 07:57:22

+16

我怀疑Set是某些语言的关键字,这可能会导致问题。 – 2009-06-24 08:10:40

+5

`Set`是VB中的一个关键字。 – 2009-11-26 01:02:07

11

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

对于更多的收藏,也有C5 Generic Collection Library

12

我使用一个围绕Dictionary<T, object>包装,将空值存储在值。这给了O(1)添加,查找和删除键,以及所有的意图和目的就像一个集合。

-4

我知道这是一个旧的线程,但我遇到了同样的问题,发现HashSet是非常不可靠的,因为给定相同的种子,GetHashCode()返回不同的代码。所以,我想,为什么不直接使用列表和隐藏这样

public class UniqueList<T> : List<T> 
{ 
    public new void Add(T obj) 
    { 
     if(!Contains(obj)) 
     { 
      base.Add(obj); 
     } 
    } 
} 

add方法由于列表使用Equals方法只是确定平等,你可以在你的T型定义Equals方法,以确保您获得理想的结果。

97

HashSet<T>数据结构:

框架类库的HashSet<T>数据结构在.NET Framework 3.5中引入的。其成员的完整列表可在MSDN reference page for HashSet<T>找到。

HashSet<T>一个mathematical set之后或多或少建模,这意味着:

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

  2. 其元素没有特定的顺序;因此该类型不实现IList<T>接口,但更基本的ICollection<T>。因此,散列集内的元素不能通过索引随机访问;他们只能通过枚举器迭代。

  3. 某些设置功能,如UnionIntersection,IsSubsetOf,IsSupersetOf可用。这些可以在使用多套工具时派上用场。

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

为什么不是List<T>

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

简短的答案是速度。随着更多元素的添加,通过正常搜索List<T>的速度非常快。 A HashSet<T>需要结构设计,以允许快速搜索和插入速度。

基准:

让我们来比较一HashSet<T>的性能速度与一个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 

现在我们来制作元素对象而不是原始类型。我写了一个快速Person类与三个字段:NameLastNameID。由于我没有包含任何比较对象的具体方法,因此所有元素都将被添加而不会发生碰撞。这次将1000 Person对象添加到每个集合中进行单个试用。 1000组试验的总次数平均为1000次。

  Average time [ms] 
---------------------------- 
HashSet<Person>   201 
List<Person>   3,000 

正如你可以看到,使用对象时,使得HashSet<T>有利的运行时间的差异成为天文数字。

11

如果你使用.NET 4.0或更高版本:

在你需要排序,然后使用SortedSet<T>的情况。否则,如果你不这样做,那么使用HashSet<T>,因为它是O(1)用于搜索和操作操作。而SortedSet<T>O(log n)用于搜索和操作操作。