C #设置collection

C# Set collection?

有人知道在C语言中是否有一个相当于Java的EDCOX1 0集合的等价物?我知道你可以通过填充但忽略这些值来模仿使用DictionaryHashTable的集合,但这不是一种非常优雅的方式。


如果您使用.NET 3.5,则可以使用HashSet。确实,.NET不能满足Java和Java的需求。

Wintelect PowerCollections也可能有帮助。


HashSet数据结构:

在.NET Framework 3.5中引入了框架类库的HashSet数据结构。其成员的完整列表可在HashSet的msdn参考页上找到。

HashSet或多或少是根据数学集合建模的,这意味着:

  • 它不能包含重复的值。

  • 它的元素没有特殊的顺序;因此类型不实现IList接口,而是更基本的ICollection接口。因此,哈希集中的元素不能通过索引随机访问;它们只能通过枚举器迭代。

  • 可以使用某些设置功能,如UnionIntersectionIsSubsetOfIsSupersetOf。当使用多个集合时,这些可以派上用场。

  • HashSetList的另一个区别是,调用哈希集的Add(item)方法返回一个布尔值:如果添加了该项,则返回true,否则返回false(因为它已经在该集中找到)。

    为什么不是List

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

    简短的回答是速度。当添加更多元素时,通过普通的List进行搜索的速度非常慢。HashSet需要一种结构设计,允许快速搜索和插入速度。

    Benchmarks:

    让我们比较一下HashSetList的性能速度。

    每一个试验都包括将0到9999的整数添加到每个集合中。然而,mod 25应用于每个整数。mod 25使项目的最大类型为25。由于添加了10000个元素,这迫使400个冲突发生,使数据结构有机会使用它们的搜索算法。在10000次试验后测量3次并取平均值。

    不要太关注测试的具体运行时间,因为它们依赖于我的硬件,但是看看它们之间的比较。

    1
    2
    3
    4
               Average time [ms]
    ----------------------------
    HashSet<T>             2,290
    List<T>                5,505

    现在让我们把元素变成对象,而不是原始类型。我写了一个快速的Person类,有三个字段:NameLastNameID。由于我没有包含任何特定的对象比较方法,因此所有元素都将在不发生冲突的情况下添加。这一次,1000个Person对象被添加到每个集合中,用于一次试验。平均出3组1000次试验的总次数。

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

    如您所见,在使用对象时,运行时间的差异会变成天文数字,这使得HashSet具有优势。


    试试HashSet:

    The HashSet(Of?T) class provides high-performance set operations. A set is a collection that contains no duplicate elements, and whose elements are in no particular order...

    The capacity of a HashSet(Of?T) object is the number of elements that the object can hold. A HashSet(Of?T) object's capacity automatically increases as elements are added to the object.

    The HashSet(Of?T) class is based on the model of mathematical sets and provides high-performance set operations similar to accessing the keys of the Dictionary(Of?TKey,?TValue) or Hashtable collections. In simple terms, the HashSet(Of?T) class can be thought of as a Dictionary(Of?TKey,?TValue) collection without values.

    A HashSet(Of?T) collection is not sorted and cannot contain duplicate elements...


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

    如果需要排序,则使用SortedSet。否则,如果不这样做,那么使用HashSet,因为它是O(1)用于搜索和操纵操作。而SortedSetO(log n)用于搜索和操纵操作。


    我使用iesi.collections http://www.codeproject.com/kb/recipes/sets.aspx

    它在很多OSS项目中使用,我第一次在NHibernate遇到它


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


    看看codeplex上的PowerCollections。除了set和orderedset之外,它还有一些其他有用的集合类型,如deque、multictionary、bag、orderedsbag、ordereddictionary和orderedmultidictionary。

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


    您可以在几个小时内实现自己的可操作集实现。当我不得不这样做的时候我就使用了这个(对不起,我手边没有代码):http://java.sun.com/j2se/1.4.2/docs/api/java/util/set.html


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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class UniqueList<T> : List<T>
    {
        public new void Add(T obj)
        {
            if(!Contains(obj))
            {
                base.Add(obj);
            }
        }
    }

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