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;需要联系 当月拿证

[SIR数据集实验][2]Java类数据集相应工具使用的小经验

这段时间安排一个师弟在继续学习SIR数据集的使用和实验方法&#xff0c;这里我先总结点经验。 如果要生成某一个数据集的Fault Matrix&#xff0c;&#xff08;虽然一般在info目录下有已经生成好的Fault Matrix&#xff0c;但按照Java Object Handbook里面的建议&#xff0c;最…

java 异步读写_Java异步与AIO

异步编程提供了一个非阻塞的&#xff0c;事件驱动的编程模型。 这种编程模型利用系统中多核执行任务来提供并行&#xff0c;因此提高了应用的吞吐率。Java异步编程通常需要使用Future&#xff0c;FutureTask和Callable&#xff0c;其中Future代表未来的某个结果&#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…

python bind sock_python SOCKET编程详细介绍

本章内容1、socket2、IO多路复用3、socketserverSocketsocket起源于Unix&#xff0c;而Unix/Linux基本哲学之一就是“一切皆文件”&#xff0c;对于文件用【打开】【读写】【关闭】模式来操作。socket就是该模式的一个实现&#xff0c;socket即是一种特殊的文件&#xff0c;一些…

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

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

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

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

python新闻评论分析_从新闻文章中提取评论

我的问题和这里问的问题类似&#xff1a;https://stackoverflow.com/questions/14599485/news-website-comment-analysis我试图从任何新闻文章中摘录评论。E、 g.我有一个新闻网址&#xff1a;http://www.cnn.com/2013/09/24/politics/un-obama-foreign-policy/我尝试在python中…

走进乔布斯的大脑

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

如何在没有 System.Drawing.Common 的情况下使用 C# 获取图片格式

之前写过一篇博文&#xff0c;用来获取图片的正确格式。博文所示代码一直工作良好&#xff0c;直到今天在将程序部署到阿里云函数计算时&#xff0c;发生了以下报错&#xff1a;System.Drawing is not supported on this platform.这表明我们不能在阿里云函数计算服务器上使用 …

Ant通配符

我们常用的匹配模式有ANT模式&#xff0c;比如acegi可以用PATTERN_TYPE_APACHE_ANT来使用ANT匹配模式&#xff0c;那什么是ANT匹配模式呢。ANT通配符有三种&#xff1a;通配符 说明 ? 匹配任何单字符 * 匹配0或者任意数量的字符 ** 匹配0或者更多的目录 例子&#xff1a;UR…

java二叉树的深度优先遍历_二叉树的广度优先遍历、深度优先遍历的递归和非递归实现方式...

1 packageSolution;23 importjava.util.LinkedList;4 importjava.util.Queue;5 importjava.util.Stack;678 public classBinaryTree {910 //二叉树节点11 public static classBinaryTreeNode {12 intvalue;13 BinaryTreeNode left;14 BinaryTreeNode right;1516 public BinaryT…

NET问答: 如何给 ASP.NET Core 配置指定端口 ?

咨询区 Drew Noakes&#xff1a;我是 ASP.NET Core 方面是新人&#xff0c;我发现程序默认的端口是 5000&#xff0c;因为要正式发布&#xff0c;所以希望把程序的端口改成 80&#xff0c;请问我该如何配置自定义端口呢 &#xff1f;回答区 Kvin Chalet&#xff1a;在 ASP.NET …

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

延续“设计激发积极生活”的理念&#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…