译文链接:https://www.infoworld.com/article/3586972/how-to-use-hashset-in-csharp.html

HashSet 是一个优化过的无序集合,提供对元素的高速查找和高性能的set集合操作,而且 HashSet 是在 .NET 3.5 中被引入的,在 System.Collection.Generic 命名空间下,这篇就来讨论一下如何使用这个 HashSet。

要运行本篇文章的案例代码,你需要安装一下 Visual Studio 2019,如果没有的话可以到官网下载一下。

使用 VS 创建一个 .NET Core 控制台程序

首先,我通过 VS2019 创建一个 .NET Core 控制台程序,创建可以参考下面步骤:

  • 打开 Visual Studio IDE

  • 点击创建 Create new project

  • Create new project 窗口上,从模板列表中选择:Console App (.NET Core)

  • 点击下一步

  • Configure your new project 界面填好你的项目名称和存放路径

这样我们就创建好了一个新项目,本文的后面部分就会在这个项目里来给大家分享 HashSet 的一些必备知识。

HashSet 到底是什么

所谓的HashSet,指的就是 System.Collections.Generic 命名空间下的 HashSet<T> 类,它是一个高性能,无序的集合,因此HashSet它并不能做排序操作,也不能包含任何重复的元素,Hashset 也不能像数组那样使用索引,所以在 HashSet 上你无法使用 for 循环,只能使用 foreach 进行迭代,HashSet 通常用在处理元素的唯一性上有着超高的性能。

HashSet<T> 实现了如下几个接口:

public class HashSet<T> : System.Collections.Generic.ICollection<T>,
System.Collections.Generic.IEnumerable<T>,
System.Collections.Generic.IReadOnlyCollection<T>,
System.Collections.Generic.ISet<T>,
System.Runtime.Serialization.IDeserializationCallback,
System.Runtime.Serialization.ISerializable
{
}

HashSet 只能包含唯一的元素,它的内部结构也为此做了专门的优化,值得注意的是,HashSet 也可以存放单个的 null 值,可以得出这么一个结论:如何你想拥有一个具有唯一值的集合,那么 HashSet 就是你最好的选择,何况它还具有超高的检索性能。

从 HashSet 中查找一个元素

如果想判断某一个元素是否在 HashSet 内,建议使用 Contains 进行判断,代码如下:

        static void Main(string[] args){HashSet<string> hashSet = new HashSet<string>();hashSet.Add("A");hashSet.Add("B");hashSet.Add("C");hashSet.Add("D");if (hashSet.Contains("D"))Console.WriteLine("The required element is available.");elseConsole.WriteLine("The required element isn’t available.");Console.ReadKey();}

HashSet中的元素唯一性

如果你向 HashSet 中插入重复的元素,它的内部会忽视这次操作而不像别的集合一样抛出异常,接下来展示一下代码:

        static void Main(string[] args){HashSet<string> hashSet = new HashSet<string>();hashSet.Add("A");hashSet.Add("B");hashSet.Add("C");hashSet.Add("D");hashSet.Add("D");Console.WriteLine("The number of elements is: {0}", hashSet.Count);Console.ReadKey();}

当你执行了这个程序,输出结果如下图:

现在可以考虑一下下面的代码段,它展示了重复的元素是如何被剔除的。

        static void Main(string[] args){string[] cities = new string[] {"Delhi","Kolkata","New York","London","Tokyo","Washington","Tokyo"};HashSet<string> hashSet = new HashSet<string>(cities);foreach (var city in hashSet){Console.WriteLine(city);}}

当你执行完上面的程序,重复的城市名称已经被移除了。

从 HashSet 中移除元素

从HashSet 中删除某一个元素可以调用 Remove 方法,它的语法结构如下:

public bool Remove (T item);

如果在集合中找到了这个元素,Remove方法将会删除这个元素并且返回true,否则返回 false。

下面的代码片段展示了如何使用 Remove 方法删除 HashSet 中的元素

string item = "D";
if(hashSet.Contains(item))
{hashSet.Remove(item);
}

如果你想删除 HashSet 中的所有元素,可以调用 Clear 方法。

HashSet 的 set操作

HashSet提供了非常多的方法用于 set集合 操作上,比如说:IntersectWith, UnionWith, IsProperSubsetOf, ExceptWith, 和 SymmetricExceptWith

IsProperSubsetOf

这个 IsProperSubsetOf 用于判断 HashSet 是否为某一个集合的完全子集,可以看下面的例子:

HashSet<string> setA = new HashSet<string>() { "A", "B", "C", "D" };
HashSet<string> setB = new HashSet<string>() { "A", "B", "C", "X" };
HashSet<string> setC = new HashSet<string>() { "A", "B", "C", "D", "E" };
if (setA.IsProperSubsetOf(setC))Console.WriteLine("setC contains all elements of setA.");
if (!setA.IsProperSubsetOf(setB))Console.WriteLine("setB does not contains all elements of setA.");

如果你执行了上面这个程序,你会在控制台上看到如下的输出:

UnionWith

UnionWith方法常用于集合的合并,比如说下面的代码:

HashSet<string> setA = new HashSet<string>() { "A", "B", "C", "D", "E" };
HashSet<string> setB = new HashSet<string>() { "A", "B", "C", "X", "Y" };
setA.UnionWith(setB);
foreach(string str in setA)
{Console.WriteLine(str);
}

当你执行完上面的代码,SetB 集合会被 SetA 集合吞掉,最后 SetA 集合将会是包括:"A", "B", "C", "D", "E", "X", and "Y"

IntersectWith

IntersectWith 方法常用于表示两个 HashSet 的交集,下面的例子或许会让你更加理解:

HashSet<string> setA = new HashSet<string>() { "A", "B", "C", "D", "E" };
HashSet<string> setB = new HashSet<string>() { "A", "X", "C", "Y"};
setA.IntersectWith(setB);
foreach (string str in setA)
{Console.WriteLine(str);
}

当你运行了上面的这段程序,只有两个 HashSet 中都存在的元素才会输出到控制台中,输出结果如下所示:

ExceptWith

ExceptWith 方法表示数学上的减法操作,这个时间复杂度是 O(N),假定你有两个HashSet 集合,分别叫 setA 和 setB,并且用了下面的语句。

setA.ExceptWith(setB);

它返回的元素为: setA中有,setB中没有 的最终结果,如果还不明白的话,使用如下代码辅助理解:

HashSet<string> setA = new HashSet<string>() { "A", "B", "C", "D", "E" };
HashSet<string> setB = new HashSet<string>() { "A", "X", "C", "Y" };
setA.ExceptWith(setB);
foreach (string str in setA)
{Console.WriteLine(str);
}

当你执行了上面这段程序,元素 B,D,E 将会输出到控制台上。

SymmetricExceptWith

SymmetricExceptWith 方法常用于修改一个 HashSet 来存放两个 HashSet 都是唯一的元素,换句话说,我要的就是两个集合都不全有的元素,如果还不明白的话,考虑下面的代码段:

HashSet<string> setA = new HashSet<string>() { "A", "B", "C", "D", "E" };
HashSet<string> setB = new HashSet<string>() { "A", "X", "C", "Y" };
setA.SymmetricExceptWith(setB);
foreach (string str in setA)
{Console.WriteLine(str);
}

当你执行完上面的代码,你会发现,setA中有而setB中没有 和 setB中有而setA中没有的元素将会输出到控制台中。

我们知道数组的平均复杂度是 O(N),这里的 n 表示数组里的元素数量,而访问 HashSet 中的某一个元素,它的复杂度为 O(1),这个常量复杂度就决定了 HashSet 在快速检索 和执行 set集合 操作上是一个非常好的选择,你也可以使用 List 去存储某些有指定顺序的元素,同时也可以包含重复的值。

更多高质量干货:参见我的 GitHub: dotnetfly

hashset如何检查重复_如何使用 C# 中的 HashSet相关推荐

  1. Java常见面试题之HashSet如何检查重复

    HashSet如何检查重复 当你把对象加入HashSet时,HashSet会先计算对象的hashcode值来判断对象加入的位置,同时也会与其他加入的对象的hashcode值作比较,如果没有相符的has ...

  2. anki卡片重复_如何在Anki中使用间隔重复来学习更快的编码

    anki卡片重复 by Steven Gilbert 史蒂文·吉尔伯特 如何在Anki中使用间隔重复来学习更快的编码 (How to use spaced repetition with Anki t ...

  3. excel工资表标题行重复_隐藏Excel报表中的重复标题

    excel工资表标题行重复 A few weeks ago we looked at a way to fill blank cells in an Excel report, so you'd be ...

  4. uniqid php 重复_如何使用php中uniqid函数生成唯一的id

    php中的uniqid是一个根据当前时间生成唯一值(ID)的函数,接下来的这篇文章我们就来详细介绍php中uniqid函数生成唯一的id的方法. php中的uniqid虽然是生成唯一的值,但是因为是基 ...

  5. java中json对象去重复_如何忽略Java中JSON对象的多个属性?

    @JsonIgnoreProperties杰克逊注解可以用于指定属性的列表或者字段的一类忽略. @JsonIgnoreProperties注释可以放在上面的类声明,而不是上面的各个属性或字段忽略. 语 ...

  6. java中hashset_Java HashSet – Java中的HashSet

    java中hashset Java HashSet is the most popular implementation of Set interface. java.util.HashSet is ...

  7. oracle插入时判断重复,Oracle在插入表之前检查重复值

    我有两个函数可以在插入到表之前检查重复值,但是我不知道哪种方法更有效? 第一种方法: select count(*) into ln_rec_cnt from ieexco_tbl t where t ...

  8. MS SQL巡检系列mdash;mdash;检查重复索引

    原文:MS SQL巡检系列--检查重复索引 前言感想:一时兴起,突然想写一个关于MS SQL的巡检系列方面的文章,因为我觉得这方面的知识分享是有价值,也是非常有意义的.一方面,很多经验不足的人,对于巡 ...

  9. uniq命令注意事项,检查重复行的时候,只会检查相邻的行。

    今天在使用uniq命令统计数量时,uniq -c总是得不到想要的效果,相同的行没有合并,例如 后来在http://ju.outofmemory.cn/entry/78365才看到,原来uniq检查重复 ...

最新文章

  1. Plant J:细菌挥发性物质和光合信号激活低铁响应途径
  2. swift_016(Swift 的闭包)
  3. 量子计算机到底神在哪里说明文,“九章”量子计算机到底有多神!
  4. 把一个中文日期时间格式字符串转为日期时间
  5. Struts2中action接受参数方法
  6. 如何正确选择仓储物流供应商?
  7. 外媒:特斯拉2.5万美元新型电动车拟2023年推出 命名Model Q
  8. java1.8win7_JDK 1.8 安装配置教程(win7 64bit )
  9. DELETE_FAILED_INTERNAL_ERROR Error while Installing APK
  10. 毕业设计 嵌入式电子时钟设计与实现
  11. 手把手教你架构3D引擎高级篇系列八
  12. 中兴java笔试题_中兴Java开发笔试题目及答案(7)
  13. Matlab时间序列分析
  14. html文件怎么传到服务器上,如何把html文件上传到云服务器
  15. 哆啦A梦:基于Prometheus的企业监控报警平台
  16. 街头篮球手游服务器维护,街头篮球手游2月9日更新维护内容详解
  17. 英语翻译太难?我一怒之下用爬虫写了两个翻译脚本
  18. 长春工业大学计算机研究生专业课,长春工业大学(专业学位)计算机技术研究生考试科目和考研参考书目...
  19. SurroundDepth:自监督多摄像头环视深度估计
  20. python爬虫专家_Python爬虫入门教程 27-100 微医挂号网专家团队数据抓取pyspider-阿里云开发者社区...

热门文章

  1. php课程 4-16 数组自定义函数(php数组-桶)
  2. 安装cnpm (npm淘宝镜像)
  3. js 判断字符是否以汉字开头
  4. Linux Mount命令浅解
  5. synchronized可重入锁
  6. 86.最少连接算法以及如何跨worker进程生效
  7. 单元测试总结反思_我的2019反思与总结
  8. python中读取文本文件_利用Python读取文本文件?
  9. linux怎样自制库_苹果开源Swift System,增加Linux支持
  10. android对象识别实验报告,Android 3相册实验报告.doc