C#中HashTable、Dictionary、ConcurrentDictionary区别

一、HashTable

HashTable表示键/值对的集合。在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似key-value的键值对,其中key通常可用来快速查找,同时key是区分大小写;value用于存储对应于key的值。Hashtable中key-value键值对均为object类型,所以Hashtable可以支持任何类型的keyvalue键值对,任何非 null 对象都可以用作键或值。

HashTable是一种散列表,他内部维护很多对Key-Value键值对,其还有一个类似索引的值叫做散列值(HashCode),它是根据GetHashCode方法对Key通过一定算法获取得到的,所有的查找操作定位操作都是基于散列值来实现找到对应的Key和Value值的。

散列函数(GetHashCode)让散列值对应HashTable的空间地址尽量不重复。

当一个HashTable被占用一大半的时候我们通过计算散列值取得的地址值可能会重复指向同一地址,这就造成哈希冲突。

C#中键值对在HashTable中的位置Position= (HashCode& 0x7FFFFFFF) % HashTable.Length,C#是通过探测法解决哈希冲突的,当通过散列值取得的位置Postion以及被占用的时候,就会增加一个位移x值判断下一个位置Postion+x是否被占用,如果仍然被占用就继续往下位移x判断Position+2*x位置是否被占用,如果没有被占用则将值放入其中。当HashTable中的可用空间越来越小时,则获取得到可用空间的难度越来越大,消耗的时间就越多。

使用方法如下:

using System;
using System.Collections;namespace WebApp
{class Program{static void Main(string[] args){   Hashtable myHash=new Hashtable();//插入myHash.Add("1","joye.net");myHash.Add("2", "joye.net2");myHash.Add("3", "joye.net3");//key 存在try{myHash.Add("1", "1joye.net");}catch{Console.WriteLine("Key = \"1\" already exists.");}//取值Console.WriteLine("key = \"2\", value = {0}.", myHash["2"]);//修改myHash["2"] = "http://www.cnblogs.com/yinrq/";myHash["4"] = "joye.net4";   //修改的key不存在则新增Console.WriteLine("key = \"2\", value = {0}.", myHash["2"]);Console.WriteLine("key = \"4\", value = {0}.", myHash["4"]);//判断key是否存在if (!myHash.ContainsKey("5")){myHash.Add("5", "joye.net5");Console.WriteLine("key = \"5\": {0}", myHash["5"]);}//移除myHash.Remove("1");if (!myHash.ContainsKey("1")){Console.WriteLine("Key \"1\" is not found.");}//foreach 取值foreach (DictionaryEntry item in myHash){Console.WriteLine("Key = {0}, Value = {1}", item.Key, item.Value);}//所有的值foreach (var item in myHash.Values){Console.WriteLine("Value = {0}",item);}//所有的keyforeach (var item in myHash.Keys){Console.WriteLine("Key = {0}", item);}Console.ReadKey();}}
}

更多参考微软官方文档:Hashtable 类

二、Dictionary

Dictionary<TKey, TValue> 泛型类提供了从一组键到一组值的映射。通过键来检索值的速度是非常快的,接近于 O(1),这是因为 Dictionary<TKey, TValue> 类是作为一个哈希表来实现的。检索速度取决于为 TKey 指定的类型的哈希算法的质量。TValue可以是值类型,数组,类或其他。

Dictionary是一种变种的HashTable,它采用一种分离链接散列表的数据结构来解决哈希冲突的问题。

简单使用代码:

using System;
using System.Collections;
using System.Collections.Generic;namespace WebApp
{class Program{static void Main(string[] args){Dictionary<string, string> myDic = new Dictionary<string, string>();//插入myDic.Add("1", "joye.net");myDic.Add("2", "joye.net2");myDic.Add("3", "joye.net3");//key 存在try{myDic.Add("1", "1joye.net");}catch{Console.WriteLine("Key = \"1\" already exists.");}//取值Console.WriteLine("key = \"2\", value = {0}.", myDic["2"]);//修改myDic["2"] = "http://www.cnblogs.com/yinrq/";myDic["4"] = "joye.net4";   //修改的key不存在则新增Console.WriteLine("key = \"2\", value = {0}.", myDic["2"]);Console.WriteLine("key = \"4\", value = {0}.", myDic["4"]);//判断key是否存在if (!myDic.ContainsKey("5")){myDic.Add("5", "joye.net5");Console.WriteLine("key = \"5\": {0}", myDic["5"]);}//移除myDic.Remove("1");if (!myDic.ContainsKey("1")){Console.WriteLine("Key \"1\" is not found.");}//foreach 取值foreach (var item in myDic){Console.WriteLine("Key = {0}, Value = {1}", item.Key, item.Value);}//所有的值foreach (var item in myDic.Values){Console.WriteLine("Value = {0}",item);}//所有的keyforeach (var item in myDic.Keys){Console.WriteLine("Key = {0}", item);}Console.ReadKey();}}
}

更多资料参考:Dictionary 类

三、ConcurrentDictionary

表示可由多个线程同时访问的键/值对的线程安全集合。

ConcurrentDictionary<TKey, TValue> framework4出现的,可由多个线程同时访问,且线程安全。用法同Dictionary很多相同,但是多了一些方法。ConcurrentDictionary 属于System.Collections.Concurrent 命名空间按照MSDN上所说:

System.Collections.Concurrent 命名空间提供多个线程安全集合类。当有多个线程并发访问集合时,应使用这些类代替 System.Collections 和 System.Collections.Generic 命名空间中的对应类型。

更多资料:ConcurrentDictionary<TKey,?TValue> 类

 

四、对比总结

分别插入500万条数据,然后遍历,看看耗时。

using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;namespace WebApp
{class Program{static Hashtable _hashtable;static Dictionary<string, string> _dictionary;static ConcurrentDictionary<string, string> _conDictionary;static void Main(string[] args){Compare(5000000);Console.ReadLine();Console.Read();}public static void Compare(int dataCount){_hashtable = new Hashtable();_dictionary = new Dictionary<string, string>();_conDictionary=new ConcurrentDictionary<string, string>();Stopwatch stopWatch = new Stopwatch();// HashtablestopWatch.Start();for (int i = 0; i < dataCount; i++){_hashtable.Add("key" + i.ToString(), "Value" + i.ToString());}stopWatch.Stop();Console.WriteLine("HashTable插" + dataCount + "条耗时(毫秒):" + stopWatch.ElapsedMilliseconds);//DictionarystopWatch.Reset();stopWatch.Start();for (int i = 0; i < dataCount; i++){_dictionary.Add("key" + i.ToString(), "Value" +i.ToString());}stopWatch.Stop();Console.WriteLine("Dictionary插" + dataCount + "条耗时(毫秒):" + stopWatch.ElapsedMilliseconds);//ConcurrentDictionarystopWatch.Reset();stopWatch.Start();for (int i = 0; i < dataCount; i++){_conDictionary.TryAdd("key" + i.ToString(), "Value" + i.ToString());}stopWatch.Stop();Console.WriteLine("ConcurrentDictionary插" + dataCount + "条耗时(毫秒):" + stopWatch.ElapsedMilliseconds);// HashtablestopWatch.Reset();stopWatch.Start();for (int i = 0; i < _hashtable.Count; i++){var key = _hashtable[i];}stopWatch.Stop();Console.WriteLine("HashTable遍历时间(毫秒):" + stopWatch.ElapsedMilliseconds);//DictionarystopWatch.Reset();stopWatch.Start();for (int i = 0; i < _hashtable.Count; i++){var key = _dictionary["key" + i.ToString()];}stopWatch.Stop();Console.WriteLine("Dictionary遍历时间(毫秒):" + stopWatch.ElapsedMilliseconds);//ConcurrentDictionarystopWatch.Reset();stopWatch.Start();for (int i = 0; i < _hashtable.Count; i++){var key = _conDictionary["key"+i.ToString()];}stopWatch.Stop();Console.WriteLine("ConcurrentDictionary遍历时间(毫秒):" + stopWatch.ElapsedMilliseconds);}}
}

运行结果:

可以看出:

大数据插入Dictionary花费时间最少

遍历HashTable最快是Dictionary的1/5,ConcurrentDictionary的1/10

单线程建议用Dictionary,多线程建议用ConcurrentDictionary或者HashTable(Hashtable tab = Hashtable.Synchronized(new Hashtable());获得线程安全的对象)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/302805.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CDA数据分析师备考必看,L1L2通用

CDA数据分析师L1,L2均可 可安排当月月底的线上考试 线上考的为双机位监考&#xff0c;但是不用担心 安全无隐患&#xff0c;需要联系 当月拿证

你以为妹子穿短裙真的是为了诱惑你吗?

全世界有3.14 % 的人已经关注了数据与算法之美每年暑假&#xff0c;ChinaJoy 都会火热进行&#xff0c;无数一年不出家门的宅男们扛着“长枪大炮”&#xff0c;向着短裙姑娘们就冲过去了。关于裙子&#xff0c;林语堂曾有过一句名言&#xff1a;“演讲应该像女士的裙子&#xf…

聊一聊Jmeter的参数化

背景 前面一篇聊了一下 JMeter 的简单使用&#xff0c;这篇聊一下 JMeter 的参数化。在开始之前先来一个单元测试的例子&#xff0c;感受一下参数化。上面是一个用 xUnit 写的单元测试&#xff0c;这个单元测试就是一个参数化的例子&#xff1a;模拟了不同的输入&#xff0c;调…

Android VNC Server New

Android VNC Server New 关于VNC请参见维基百科&#xff1a;http://zh.wikipedia.org/wiki/VNC关于执行Android VNC Server&#xff0c;请参见前一篇文章&#xff1a;点击链接 一、VNC下载1&#xff09;fastdroid-vncAndroid VNC Server开源项目 http://code.google.com/p/fast…

EPPlus导出Excel感觉很不错~~~

前言导出成为很多系统的必备功能&#xff0c;之前分享过导出PDF的功能&#xff0c;这里来分享一下Excel的导出&#xff1b;提到Excel导出&#xff0c;NPOI肯定是很多小伙伴的首选&#xff0c;在以往的项目中也用其完成了很多导出需求&#xff1b;对于NPOI&#xff0c;个人感觉使…

[文摘]标准的软件开发过程

为什么80%的码农都做不了架构师&#xff1f;>>> 软件开发的标准过程包括六个阶段&#xff0c;而六个阶段需要编写的各类文件达 14 种之多&#xff0c;在每个阶段需要编写哪些文件&#xff0c;以及这些文件的主要内容见下&#xff1a; 1.可行性与计划研究阶段 可行性…

走进乔布斯的大脑

全世界有3.14 % 的人已经关注了数据与算法之美你永远也无法走进苹果教父乔布斯神秘的大脑&#xff0c;但下面的图可以让你多靠近了解他一点。人们都想走进乔帮主的大脑里看看他的想法&#xff0c;可惜他太难以捉摸了。但是&#xff0c;有个有趣的方法&#xff0c;至少可以让人们…

硬货 | 一片小小的薄膜,却可以粘住全世界!

延续“设计激发积极生活”的理念&#xff0c;在这个中秋&#xff0c;GYMLIVING特别推出月亮概念新产品&#xff0c;在便利生活的同时&#xff0c;为你带来一份浪漫和惊喜&#xff01;说起月亮&#xff0c;除了阴晴圆缺&#xff0c;月球漫步更让它成了浪漫的代名词。有公司正计划…

使用域超级管理员打开Exchange 2010发现没有权限

1.使用administrator管理员打开EMC却报没有权限。 2.发现此问题&#xff0c;系邮件服务器本身上安装了outlook软件&#xff0c;并配置了使用非administrator账户收信。并有做了Windows保存了用户凭据&#xff0c;造成帐号使用上的混乱&#xff0c;导致连接Exchange服务器时使用…

C# 将多个图片合并成TIFF文件的两种方法

最近需要用到TIF格式的文件&#xff0c;研究了一段时间&#xff0c;终于有点结果了&#xff0c;发现两种方式&#xff0c;第一种是使用BitMiracle.LibTiff.NET&#xff0c;直接在Nuget上安装即可&#xff0c;第二种是使用RasterEdge.DocImageSDK&#xff0c;要从官网下载dll包第…

高等数学、线性代数、概率论与数理统计、几何学这些知识可以用来干什么?主要应用有哪些?...

全世界有3.14 % 的人已经关注了数据与算法之美知乎谢漠烟其他三项&#xff0c;不研究少数工科确实没用&#xff0c;但概率统计真乃应用数学之王。鄙人学业从数学院开始&#xff0c;以经济学院结束&#xff0c;现在在证券公司做苦逼行业研究&#xff0c;深有体会。概率统计抛开了…

HDU 2896 病毒侵袭【AC自动机】

Problem Description当太阳的光辉逐渐被月亮遮蔽&#xff0c;世界失去了光明&#xff0c;大地迎来最黑暗的时刻。。。。在这样的时刻&#xff0c;人们却异常兴奋——我们能在有生之年看到500年一遇的世界奇观&#xff0c;那是多么幸福的事儿啊~~但网路上总有那么些网站&#xf…

风靡全球的人工智能,如何赶上这班车?

目前&#xff0c;机器学习的使用日渐成为趋势。作为人工智能的核心&#xff0c;机器学习是一门多领域的交叉学科&#xff0c;专门研究计算机模拟或实现人类学习行为的方法&#xff0c;以获取新的知识或技能&#xff0c;重新组织已有的知识结构使之不断改善自身的性能。简单来说…

java spark读写hdfs_Spark读取HDFS数据输出到不同的文件

最近有一个需求是这样的&#xff1a;原来的数据是存储在MySQL&#xff0c;然后通过Sqoop将MySQL的数据抽取到了HDFS集群上&#xff0c;抽取到HDFS上的数据都是纯数据&#xff0c;字段值之间以\t分隔&#xff0c;现在需要将这部分数据还原为json格式的&#xff0c;因为这样做的原…

15个创意的电梯广告

如果你走进任何一个城市&#xff0c;几乎每一个地方有电梯&#xff0c;但是你发现具有创意的广告电梯了吗&#xff0c;分享给大家15个不同城市的创意的电梯广告&#xff0c;作为设计师可以帮助你 Accor Air Asia Becel Body World Coke Zero Consol Energy Fiat Punto Forklift…

揭秘全球开发最新趋势!JS开发者达1380万,C#超越PHP,Rust增长最快

文 | 白开水出品 | OSC开源社区&#xff08;ID&#xff1a;oschina2013&#xff09;研究公司 SlashData 最新发布的”State of the Developer Nation“第 20 版报告指出&#xff0c;全球开发者社区在过去六个月中的经历了巨大的增长。据估计&#xff0c;截至 2021 年第一季度&a…

怎样判断漂亮女孩是不是单身的?

全世界有3.14 % 的人已经关注了数据与算法之美不解风情的死理性派们在情感生活中不免会遇到这样悲催的一幕&#xff1a;偶然间遇到一位心仪的漂亮女孩&#xff0c;从此日思夜想&#xff0c;废寝忘食&#xff0c;开始了漫长的暗恋之旅。等到一日&#xff0c;在无尽的纠结中&…

java开源cad_寻找 AutoCAD 替代品,5款免费开源 CAD 软件推荐

FreeCADFreeCAD 是一种通用的3D CAD建模。完全开源(LGPL许可证)FreeCAD 直接的目的是在机械工程和产品设计&#xff0c;也适合在更广泛的用途&#xff0c;如建筑行业或其他工程专业&#xff0c;工程相关领域。FreeCAD 全平台通用&#xff0c;能完美工作在 Windows、Linux 和 ma…

快速弄懂陌生领域是一项“赚钱”的能力

大家好&#xff0c;我是Z哥。有时候&#xff0c;我们被动的需要去了解一个新行业或者领域。比如&#xff0c;工作需要、投资需要等等。在这个时候&#xff0c;你能不能快速弄懂一个行业的80%&#xff0c;成为一个内行就很关键了。毕竟时机可是很重要的。比如&#xff0c;你想了…

java弹窗 触发事件_关于ElementUI中MessageBox弹框的取消键盘触发事件(enter,esc)关闭弹窗(执行事件)的解决方法...

好久没见了在项目中遇到一个小小的需求&#xff0c;总结了一下&#xff01;详细我就不介绍了&#xff0c;相信大家用过的话&#xff0c;很了解。详见文档----------->http://element-cn.eleme.io/#/zh-CN/component/message-box#messagebox-dan-kuang项目需求——关于Elemen…