C#集合集?

时间:2008-10-08 16:33:59

标签: c# .net collections set

有人知道在C#中是否有与Java Set集合相当的好处吗?我知道您可以使用DictionaryHashTable通过填充但忽略值来模仿集合,但这不是一种非常优雅的方式。

9 个答案:

答案 0 :(得分:402)

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

Wintellect PowerCollections也可能有所帮助。

答案 1 :(得分:115)

HashSet<T>数据结构:

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

{p> HashSet<T>或多或少是在mathematical set之后建模的,这意味着:

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

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

  3. 某些设置功能可用,例如UnionIntersectionIsSubsetOfIsSupersetOf。当使用多组时,这些可以派上用场。

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

    为什么不false

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

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

    <强>基准:

    让我们比较HashSet<T>HashSet<T>的效果速度。

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

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

    List<T>

    现在让我们创建元素对象而不是基本类型。我写了一个包含三个字段的快速 Average time [ms] ---------------------------- HashSet<T> 2,290 List<T> 5,505 课程:PersonNameLastName。由于我没有包含任何比较对象的特定方法,因此将添加所有元素而不会发生冲突。这次,为每次试验添加了1,000 ID个对象。平均3组1000次试验的总次数。

    Person

    如您所见,使用对象时,运行时间的差异变得天文数字,使 Average time [ms] ---------------------------- HashSet<Person> 201 List<Person> 3,000 变得有利。

答案 2 :(得分:106)

尝试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)集合未排序且不能包含重复元素...

答案 3 :(得分:18)

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

如果您需要排序,请使用SortedSet<T>。否则,如果不这样做,则使用HashSet<T>,因为O(1)用于搜索和操作操作。而SortedSet<T>O(log n)用于搜索和操作操作。

答案 4 :(得分:14)

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

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

答案 5 :(得分:12)

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

答案 6 :(得分:11)

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

对于更多收藏品,还有C5 Generic Collection Library

答案 7 :(得分:0)

您可以在几个小时内实现自己的可行集实现。我必须这样做时使用了这个(对不起,我没有方便的代码):http://java.sun.com/j2se/1.4.2/docs/api/java/util/Set.html

答案 8 :(得分:-5)

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

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

因为List仅使用Equals方法来确定相等性,所以可以在T类型上定义Equals方法以确保获得所需的结果。