C#解惑:HashSet<T>类
原贴: https://blog.csdn.net/X_X_OO/article/details/52529548
https://www.cnblogs.com/refuge/p/9465466.html
HashSet<T>
是一个相对“冷门”的类型,平时在项目中用得不多,但是在特定的业务中可以大用。
先来了解下HashSet<T>
类,主要被设计用来存储集合,做高性能集运算,例如两个集合求交集、并集、差集等。从名称可以看出,它是基于Hash的,可以简单理解为没有Value的Dictionary。
HashSet<T>
不能用索引访问,不能存储重复数据,元素T必须正确实现了Equals
和GetHashCode
。
HashSet<T>
的一些特性如下:
HashSet<T>
中的值不能重复且没有顺序。HashSet<T>
的容量会按需自动添加。
HashSet<T>
的优势和与List<T>
的比较
HashSet<T>
最大的优势是检索的性能,简单的说它的Contains方法的性能在大数据量时比List<T>
好得多。曾经做过一个测试,将800W条int类型放在List<int>
集合中,使用Contains判断是否存在,速度巨慢,而放在HashSet<int>
性能得到大幅提升。
在内部算法实现上,HashSet<T>
的Contains方法复杂度是O(1),List<T>
的Contains方法复杂度是O(n),后者数据量越大速度越慢,而HashSet<T>
不受数据量的影响。
所以在集合的目的是为了检索的情况下,我们应该使用HashSet<T>
代替List<T>
。比如一个存储关键字的集合,运行的时候通过其Contains方法检查输入字符串是否关键字。
在3.5之前,想用哈希表来提高集合的查询效率,只有Hashtable和Dictionary两种选择,而这两种都是键-值方式的存储。但有些时候,我们只需要其中一个值,例如一个Email集合,如果用泛型哈希表来存储,往往要在Key和Value各保存一次,不可避免的要造成内存浪费。而HashSet只保存一个值,更加适合处理这种情况。
此外,HashSet的Add方法返回bool值,在添加数据时,如果发现集合中已经存在,则忽略这次操作,并返回false值。而Hashtable和Dictionary碰到重复添加的情况会直接抛出错误。
从使用上来看,HashSet和线性集合List更相似一些,但前者的查询效率有着极大的优势。假如,用户注册时输入邮箱要检查唯一性,而当前已注册的邮箱数量达到10万条,如果使用List进行查询,需要遍历一次列表,时间复杂度为O(n),而使用HashSet则不需要遍历,通过哈希算法直接得到列表中是否已存在,时间复杂度为O(1),这是哈希表的查询优势。
和List的区别
HashSet是Set集合,它只实现了ICollection接口,在单独元素访问上,有很大的限制:
跟List相比,不能使用下标来访问元素,如:list[1] 。
跟Dictionary相比,不能通过键值来访问元素,例如:dic[key],因为HashSet每条数据只保存一项,并不采用Key-Value的方式,换句话说,HashSet中的Key就是Value,假如已经知道了Key,也没必要再查询去获取Value,需要做的只是检查值是否已存在。
所以剩下的仅仅是开头提到的集合操作,这是它的缺点,也是特点。
集合运算
IntersectWith (IEnumerable other) (交集)
- public void IntersectWithTest()
- {
- HashSet<int> set1 = new HashSet<int>() { 1, 2, 3 };
- HashSet<int> set2 = new HashSet<int>() { 2, 3, 4 };
- set1.IntersectWith(set2);
- foreach (var item in set1)
- {
- Console.WriteLine(item);
- }
- //输出:2,3
- }
UnionWith (IEnumerable other) (并集)
public void UnionWithTest()
{
HashSet set1 = new HashSet() { 1, 2, 3 };
HashSet set2 = new HashSet() { 2, 3, 4 };
- set1.UnionWith(set2);
- foreach (var item in set1)
- {
- Console.WriteLine(item);
- }
- //输出:1,2,3,4
- }
ExceptWith (IEnumerable other) (排除)
public void ExceptWithTest()
{
HashSet set1 = new HashSet() { 1, 2, 3 };
HashSet set2 = new HashSet() { 2, 3, 4 };
- set1.ExceptWith(set2);
- foreach (var item in set1)
- {
- Console.WriteLine(item);
- }
- //输出:1
- }
C#解惑:HashSet<T>类的更多相关文章
- (转) C#解惑:HashSet<T>类
HashSet<T>是一个相对“冷门”的类型,平时在项目中用得不多,但是在特定的业务中可以大用. 先来了解下HashSet<T>类,主要被设计用来存储集合,做高性能集运算,例如 ...
- HashSet<T>类 用法
HashSet<T>类主要是设计用来做高性能集运算的,例如对两个集合求交集.并集.差集等.集合中包含一组不重复出现且无特性顺序的元素 改变集的值的方法: HashSet<T>的 ...
- HashSet<T>类
HashSet<T>类主要是设计用来做高性能集运算的,例如对两个集合求交集.并集.差集等.集合中包含一组不重复出现且无特性顺序的元素. HashSet<T>的一些特性如下: 1 ...
- (转)HashSet<T>类
转载于:http://www.importnew.com/6931.html HashSet<T>类主要是设计用来做高性能集运算的,例如对两个集合求交集.并集.差集等.集合中包含一组不重复 ...
- HashSet 实现类
HashSet 实现类 通过 HashCode 判断元素是否存在,若存在则不添加,否则添加以此实现唯一性 常用方法 Modifier and Type Method and Description b ...
- Java解惑五:类之谜
本文是依据JAVA解惑这本书,做的笔记.电子书见:http://download.csdn.net/detail/u010378705/7527721 谜题46 函数重载的问题. JAVA重载解析过程 ...
- Set接口HashSet实现类
java.util.Set接口 extends Collection接口 Set特点: 1.不允许有重复的元素 2.没有索引,没有带索引的方法,也不能使用普通的for遍历 java.util.Hash ...
- 微软在 .NET 3.5 新增了一个 HashSet 类,在 .NET 4 新增了一个 SortedSet 类,本文介绍他们的特性,并比较他们的异同。
微软在 .NET 3.5 新增了一个 HashSet 类,在 .NET 4 新增了一个 SortedSet 类,本文介绍他们的特性,并比较他们的异同. .NET Collection 函数库的 Has ...
- Nullable类型和HashSet<T>集合
今天接触到两个新的类型,查了一下才发现它们已经出现好久了,特作一下标记 Nullable结构 在System命名空间下,在 .NET Framework 2.0 版中是新增的:用它定义的值类型的对象与 ...
随机推荐
- 安卓构架组件——概述 Android Architecture Components
谷歌官文文档地址:https://developer.android.google.cn/topic/libraries/architecture 安卓构架组建是库的集合:帮助你设计健壮的.易测试的. ...
- 20180306-time&datetime模块
在开始介绍时间模块之前先说明几点: 一. Python中常用以下几种形式表示时间 1.时间戳 2.格式化的时间字符串 3.元组(struct_time)(共九个元素),由于Python的time模块实 ...
- Springmvc上传过程中遇到的错误
问题1: org.springframework.web.util.NestedServletException: Handler processing failed; nested exceptio ...
- python常用函数 I
iter(iterable) 可以生成一个迭代器. 例子: islice(iterator, int, int) itertools的islice方法为迭代器生成器提供切片操作. 例子: izip_l ...
- PL SQL安装
首先,在官网下载PL SQL 的对应版本,本机是64位的就下载64位的,网址:https://www.allroundautomations.com/downloads.html#PLS 点击应用程序 ...
- 应用程序无法正常启动(0xc000007b)。请单击“确定”关闭应用程序
一开始是报缺少dll,随便在电脑里找个同名的dll放下面就报这个错误,网上查的都没有用.后来又找了一个dll,问题就解决了,所以是dll不对造成的.
- 我们为什么选择Ceph来建立块存储
我们为什么选择Ceph来建立块存储?国内知名黑客组织东方联盟是这样回答的,卷管理器的大小和增长受到管理程序的驱动器补充的限制,与其他Droplet共享.一旦Droplet被摧毁,储存就会被释放.术语“ ...
- hibernate 5原生sql查询测试学习代码
基本查询 import java.util.List; import org.hibernate.SQLQuery; import org.hibernate.Session; import org. ...
- Sublime Text3添加C++编译与运行
安装MinGW 1.安装MinGW ,其安装方法一直下一步,安装完后点Continue会出现一个窗口,在Basic Setup下标记所有包,然后在菜单里点"Apply Changes&quo ...
- 4412 使用小度wifi
本文转载至:https://blog.csdn.net/robertsong2004/article/details/42985223 作者:刘老师,华清远见嵌入式学院讲师. FS_4412可以同链接 ...