【问题标题】:C# Set collection?C#集合集合?
【发布时间】:2010-09-16 01:40:01
【问题描述】:

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

【问题讨论】:

    标签: c# .net collections set


    【解决方案1】:

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

    【讨论】:

    • 不幸的是,直到最近才添加 HashSet。如果您使用的是旧版本的框架,您将不得不坚持使用您的 munged Dictionary 或 Hashtable。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      Wintellect PowerCollections 也可能有帮助。

      【讨论】:

      • 我怀疑 Set 是某些语言中的关键字,这可能会导致问题。
      • @Manish:不,不是。请参阅 C# 3 规范的第 2.4.3 节。它只对属性有特殊意义。
      • 之所以称它为 HashSet 而不仅仅是 Set,与 Java 中的相同——“Set”描述了一个接口,而“HashSet”描述了一个实现——具体来说,这是一个由哈希图。通过这种方式,我们知道(或应该强烈期望)插入和访问应该花费 O(1) 访问时间,而“LinkedListSet”会导致我们预期插入和访问花费 O(n) 时间。
      • 你是什么意思“.NET 不像 Java 那样满足集合。”?与 Java 相比,这个 Set 是否不完美?
      • @Louis:你说的是哪个系列? Java 有 很多 种不同的 Set 实现,适用于各种情况。 .NET 在 .NET 3.5(HashSet)中有一个,在 .NET 4 中有两个(HashSet 和 SortedSet)。我们不得不等到 .NET 3.5 才开始使用这一事实非常令人惊讶。
      【解决方案4】:

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

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

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

      【讨论】:

      • 您不想使用它的原因是因为List.Contains 具有O(n) 复杂性,这意味着您的Add 方法现在也变为O(n) 复杂性。假设不需要调整内部集合的大小,Add 对于ListHashMap 的复杂性应该是O(1)。 TLDR:这可行,但它很老套,效率较低。
      • 当然,如果您的对象没有为 GetHashCode 返回适当的值,则不应将它们放入基于哈希的容器中。修复 GetHashCode 比使用效率较低的容器要好。
      【解决方案5】:

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

      【讨论】:

      • 你的意思是它大致相当于std::unordered_set。 std::set 是有序的。例如,您可以快速找到一个范围的起点和终点,并从头到尾进行迭代,以键顺序访问项目。 SortedDictionary is 大致相当于 std::set.
      【解决方案6】:

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

      更多收藏,还有C5 Generic Collection Library

      【讨论】:

        【解决方案7】:

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

        在很多 OSS 项目中都有用到,我是在 NHibernate 中第一次接触到的

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-06-04
          • 1970-01-01
          • 2015-11-30
          • 1970-01-01
          • 2012-05-10
          • 1970-01-01
          • 2012-07-07
          相关资源
          最近更新 更多