【发布时间】:2011-06-01 07:40:53
【问题描述】:
哈希集 C# HashSet 数据结构是在 .NET Framework 3.5 中引入的。可在HashSet MSDN 页面上找到已实施成员的完整列表。
- 用在什么地方?
- 您为什么要使用它?
【问题讨论】:
-
它在内部使用哈希表。如果你有一个好的哈希表实现(例如 Dictionary
),你可以自己轻松实现 HashSet。
哈希集 C# HashSet 数据结构是在 .NET Framework 3.5 中引入的。可在HashSet MSDN 页面上找到已实施成员的完整列表。
【问题讨论】:
HashSet 包含一组对象,但它允许您轻松快速地确定对象是否已经在集合中。它通过在内部管理一个数组并使用从对象的哈希码计算的索引来存储对象来实现这一点。 Take a look here
HashSet 是一个包含唯一元素的无序集合。它具有标准的集合操作 Add、Remove、Contains,但由于它使用基于散列的实现,因此这些操作是 O(1)。 (例如,与 List 不同,包含和删除是 O(n)。)HashSet 还提供标准集合操作,例如 union、intersection 和 对称差。 Take a look here
Set 有不同的实现。有些通过散列元素使插入和查找操作超快。但是,这意味着添加元素的顺序会丢失。其他实现以较慢的运行时间为代价来保留添加的顺序。
C# 中的HashSet 类采用第一种方法,因此不 保留元素的顺序。它比普通的List 快得多。一些基本的基准测试表明,HashSet 在处理主要类型(int、double、bool 等)时要快得多。使用类对象时速度要快得多。所以这一点是 HashSet 很快。
HashSet 的唯一问题是无法通过索引访问。要访问元素,您可以使用枚举器或使用内置函数将 HashSet 转换为 List 并遍历它。 Take a look here
【讨论】:
HashSet 具有内部结构(哈希),可以在其中快速搜索和识别项目。缺点是遍历HashSet(或按索引获取项目)相当慢。
那么为什么有人想要知道一个条目是否已经存在于集合中呢?
HashSet 有用的一种情况是从可能存在重复项的列表中获取不同的值。将项目添加到HashSet 后,可以快速确定该项目是否存在(Contains 运算符)。
HashSet 的其他优点是 Set 操作:IntersectWith、IsSubsetOf、IsSupersetOf、Overlaps、SymmetricExceptWith、UnionWith。
如果您熟悉object constraint language,那么您将识别这些集合操作。您还将看到它离可执行 UML 的实现更近了一步。
【讨论】:
从应用程序的角度来看,如果只需要避免重复,那么 HashSet 就是您要寻找的,因为它是查找、插入和删除 complexities are O(1) - constant。这意味着HashSet 有多少元素无关紧要,检查是否存在这样的元素需要相同的时间,而且由于您也在 O(1) 处插入元素,因此它非常适合这种东西。
【讨论】:
简单地说,并没有透露厨房的秘密:
一般来说,集合是不包含重复元素且其元素没有特定顺序的集合。因此,A HashSet<T> 类似于通用 List<T>,但针对快速查找(通过哈希表,顾名思义)进行了优化,但以丢失订单为代价。
【讨论】: