定义:啥是HashSet?

Posted

技术标签:

【中文标题】定义:啥是HashSet?【英文标题】:Define: What is a HashSet?定义:什么是HashSet? 【发布时间】:2011-06-01 07:40:53 【问题描述】:

哈希集 C# HashSet 数据结构是在 .NET Framework 3.5 中引入的。可在HashSet MSDN 页面上找到已实施成员的完整列表。

    用在什么地方? 您为什么要使用它?

【问题讨论】:

en.wikipedia.org/wiki/Set_(computer_science) When should I use the HashSet<T> type?的可能重复 它在内部使用哈希表。如果你有一个好的哈希表实现(例如 Dictionary),你可以自己轻松实现 HashSet。 【参考方案1】:

      HashSet 包含一组对象,但它允许您轻松快速地确定对象是否已经在集合中。它通过在内部管理一个数组并使用从对象的哈希码计算的索引来存储对象来实现这一点。 Take a look here

      HashSet 是一个包含唯一元素的无序集合。它具有标准的集合操作 Add、Remove、Contains,但由于它使用基于散列的实现,因此这些操作是 O(1)。 (例如,与 List 不同,包含和删除是 O(n)。)HashSet 还提供标准集合操作,例如 unionintersection 和 对称差。 Take a look here

    Set 有不同的实现。有些通过散列元素使插入和查找操作超快。但是,这意味着添加元素的顺序会丢失。其他实现以较慢的运行时间为代价来保留添加的顺序。

C# 中的HashSet 类采用第一种方法,因此 保留元素的顺序。它比普通的List 快得多。一些基本的基准测试表明,HashSet 在处理主要类型(int、double、bool 等)时要快得多。使用类对象时速度要快得多。所以这一点是 HashSet 很快。

HashSet 的唯一问题是无法通过索引访问。要访问元素,您可以使用枚举器或使用内置函数将 HashSet 转换为 List 并遍历它。 Take a look here

【讨论】:

有两个东西,hashset 和类似的东西是 .NET 的,而不是 C# 的。 HashSet 也不保留顺序。尝试从哈希集中添加和删除项目,你会知道如果你稍后迭代.. 那么 HashSet 和 Dictionary 不是一回事吗?有什么区别?【参考方案2】:

HashSet 具有内部结构(哈希),可以在其中快速搜索和识别项目。缺点是遍历HashSet(或按索引获取项目)相当慢。

那么为什么有人想要知道一个条目是否已经存在于集合中呢?

HashSet 有用的一种情况是从可能存在重复项的列表中获取不同的值。将项目添加到HashSet 后,可以快速确定该项目是否存在(Contains 运算符)。

HashSet 的其他优点是 Set 操作:IntersectWithIsSubsetOfIsSupersetOfOverlapsSymmetricExceptWithUnionWith

如果您熟悉object constraint language,那么您将识别这些集合操作。您还将看到它离可执行 UML 的实现更近了一步。

【讨论】:

回复:缺点。不,遍历 HashSet 非常快。其次,无法通过索引获取项目。实际上,元素是无序存储的。 @Nigel Touch。如果您不关心索引(添加它们的顺序),迭代会很快。但是,如果您关心索引,那么索引必须与每个散列键一起存储,因此它可能会相当慢,因为必须彻底搜索列表以检索正确的项目。这种行为与按添加顺序对项目进行索引的列表非常不同。 它为什么会很快是有道理的,因为没有两个哈希是相同的。使查询能够利用“短路”方法,快速排除某些条件。【参考方案3】:

从应用程序的角度来看,如果只需要避免重复,那么 HashSet 就是您要寻找的,因为它是查找、插入和删除 complexities are O(1) - constant。这意味着HashSet 有多少元素无关紧要,检查是否存在这样的元素需要相同的时间,而且由于您也在 O(1) 处插入元素,因此它非常适合这种东西。

【讨论】:

【参考方案4】:

简单地说,并没有透露厨房的秘密: 一般来说,集合是不包含重复元素且其元素没有特定顺序的集合。因此,A HashSet&lt;T&gt; 类似于通用 List&lt;T&gt;,但针对快速查找(通过哈希表,顾名思义)进行了优化,但以丢失订单为代价。

【讨论】:

但是 HashSet 是否可以存储两个具有相同数据的对象,例如两个 Product 类,每个类具有相同的属性和相同的内容? 我想我们永远不会知道 @JohanHerstad 假设您的类的 EqualityComparer 关心这些属性,或者您使用关心这些属性的 IEqualityComparer 构造 HashSet,我不明白为什么它不会。 documentation for HashSet 清楚地表明它依赖于一个或另一个来确定唯一性。

以上是关于定义:啥是HashSet?的主要内容,如果未能解决你的问题,请参考以下文章

java中定义HashSet时能否指定其容量?若能,如何定义?

HashSet使用自定义IComparer排序而不使用LINQ

HashSet存储自定义类型元素

.NET中的HashSet

HashSet和TreeSet的区别

HashSet存储过程中如何排除不同的自定义对象?