热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

聊聊C#中HashTable与Dictionary的区别说明

这篇文章主要介绍了聊聊C#中HashTable与Dictionary的区别说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

1. 哈希表(HashTable)简述

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

2. 什么情况下使用哈希表

(1)某些数据会被高频率查询(2)数据量大(3)查询字段包含字符串类型(4)数据类型不唯一

3. 哈希表的使用方法

哈希表需要使用的namespace

using System.Collections;
using System.Collections.Generic;

哈希表的基本操作:

//添加一个keyvalue键值对:
HashtableObject.Add(key,value);
//移除某个keyvalue键值对:
HashtableObject.Remove(key);
//移除所有元素:      
HashtableObject.Clear(); 
// 判断是否包含特定键key:
HashtableObject.Contains(key);

控制台程序例子:

using System;
using System.Collections; //file使用Hashtable时,必须引入这个命名空间
class Program
{
 public static void Main()
 {
   Hashtable ht = new Hashtable(); //创建一个Hashtable实例
   ht.Add("北京", "帝都"); //添加keyvalue键值对
   ht.Add("上海", "魔都");
   ht.Add("广州", "省会");
   ht.Add("深圳", "特区");
   string capital = (string)ht["北京"];
   Console.WriteLine(ht.Contains("上海")); //判断哈希表是否包含特定键,其返回值为true或false
   ht.Remove("深圳"); //移除一个keyvalue键值对
   ht.Clear(); //移除所有元素
 }
}   

哈希表中使用多种数据类型的例子:

using System;
using System.Collections;
class Program
{
  static Hashtable GetHashtable()
  {
    Hashtable hashtable = new Hashtable();
    
    hashtable.Add("名字", "小丽");
    hashtable.Add("年龄", 22);
    return hashtable;
  }
  static void Main()
  {
    Hashtable hashtable = GetHashtable();
    string name = (string)hashtable["名字"];
    Console.WriteLine(name);
    int age = (int)hashtable["年龄"];
    Console.WriteLine(age);
  }
}

当获取哈希表中数据时,如果类型声明的不对,会出现InvalidCastException错误。使用as-statements可以避免该错误。

using System;
using System.Collections;
using System.IO;
class Program
{
  static void Main()
  {
  Hashtable hashtable = new Hashtable();
  hashtable.Add(100, "西安");
  // 能转换成功
  string value = hashtable[100] as string;
  if (value != null)
  {
    Console.WriteLine(value);
  }
  // 转换失败,获取的值为null,但不会抛出错误。
  StreamReader reader = hashtable[100] as StreamReader;
  if (reader == null)
  {
     Console.WriteLine("西安不是StreamReader型");
  }
  // 也可以直接获取object值,再做判断
  object value2 = hashtable[100];
  if (value2 is string)
  {
    Console.Write("这个是字符串型: ");
    Console.WriteLine(value2);
  }
  }
}

4. 遍历哈希表

遍历哈希表需要用到DictionaryEntry Object,代码如下:

for(DictionaryEntry de in ht) //ht为一个Hashtable实例
{
  Console.WriteLine(de.Key); //de.Key对应于keyvalue键值对key
  Console.WriteLine(de.Value); //de.Key对应于keyvalue键值对value
}

遍历键

foreach (int key in hashtable.Keys)
{
  Console.WriteLine(key);
}

遍历值

foreach (string value in hashtable.Values)
{
  Console.WriteLine(value);
}

5. 对哈希表进行排序

对哈希表按key值重新排列的做法:

ArrayList akeys=new ArrayList(ht.Keys); 
akeys.Sort(); //按字母顺序进行排序
foreach(string key in akeys)
{
  Console.WriteLine(key + ": " + ht[key]); //排序后输出
}

6. 哈希表的效率

System.Collections下的哈希表(Hashtable)和System.Collections.Generic下的字典(Dictionary)都可用作lookup table,下面比较一下二者的执行效率。

Stopwatch sw = new Stopwatch();
Hashtable hashtable = new Hashtable();
Dictionary dictiOnary= new Dictionary();
int countNum = 1000000;
sw.Start();
for (int i = 0; i 

由此可见,添加数据时Hashtable快。频繁调用数据时Dictionary快。

结论:

Dictionary是泛型的,当K或V是值类型时,其速度远远超过Hashtable。

补充:C# 哈希表Hashtable与字典表Dictionary的比较。

一、Hashtable 和 Dictionary 类型

1):单线程程序中推荐使用 Dictionary, 有泛型优势, 且读取速度较快, 容量利用更充分.

2):多线程程序中推荐使用 Hashtable, 默认的 Hashtable 允许单线程写入, 多线程读取, 对 Hashtable 进一步调用 Synchronized()方法可以获得完全线程安全的类型. 而Dictionary 非线程安全, 必须人为使用 lock 语句进行保护, 效率大减.

3):Dictionary 有按插入顺序排列数据的特性 (注: 但当调用 Remove() 删除过节点后顺序被打乱), 因此在需要体现顺序的情境中使用 Dictionary 能获得一定方便.

在使用哈希表保存集合元素(一种键/值对)时,首先要根据键自动计算哈希代码,以确定该元素的保存位置,再把元素的值放入相应位置所指向的存储桶中。在查找时,再次通过键所对应的哈希代码到特定存储桶中搜索,这样将大大减少为查找一个元素进行比较的次数。

HashTable中的key/value均为object类型,由包含集合元素的存储桶组成。存储桶是 HashTable中各元素的虚拟子组,与大多数集合中进行的搜索和检索相比,存储桶可令搜索和检索更为便捷。每一存储桶都与一个哈希代码关联,该哈希代码是使用哈希函数生成的并基于该元素的键。HashTable的优点就在于其索引的方式,速度非常快。如果以任意类型键值访问其中元素会快于其他集合,特别是当数据量特别大的时候,效率差别尤其大。

HashTable的应用场合有:做对象缓存,树递归算法的替代,和各种需提升效率的场合。

二、哈希表Hashtabl

Hastable是哈希表的实现,能根据关键字取关键值,这key的类型是object, value的类型也是object。

在哈希表中添加一个key/value键值对:HashtableObject.Add(key,value);

在哈希表中去除某个key/value键值对:HashtableObject.Remove(key);

从哈希表中移除所有元素: HashtableObject.Clear();

判断哈希表是否包含特定键key: HashtableObject.Contains(key);

遍历Hashtable对象的两种方法:

由于Hashtable每个元素都是一个键/值对,因此元素类型既不是键的类型,也不是值的类型,而是DictionaryEntry类型。

Hashtable示例代码

Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->//方法一
foreach (System.Collections.DictionaryEntry de in myHashtable)
{
  //注意HastTable内存储的默认类型是object,需要进行转换才可以输出
  Console.WriteLine(de.Key.ToString());
  Console.WriteLine(de.Value.ToString());
}
 
 
//方法二
System.Collections.IDictionaryEnumerator enumerator = myHashtable.GetEnumerator();
 
while (enumerator.MoveNext())
{
  Console.WriteLine(enumerator.Key);    // Hashtable关健字
  Console.WriteLine(enumerator.Value);   // Hashtable值
}

三、字典Dictionary

Dictionary是Hastbale的泛型实现。

Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->//遍历键
foreach (string key in myDictionary.Keys)
{
  //遍历某键的值
  foreach (string val in myDictionary[key])
  {
 
  }
}

由于 Dictionary 是键和值的集合,因此元素类型并非键类型或值类型。相反,元素类型是键类型和值类型的 KeyValuePair 。

字典遍历示例 
 
Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->foreach (KeyValuePair kvp in myDictionary)
{
  string key = kvp.Key;//key包含了字典里的键
  for (int i = 0; i 

示例 :

代码

Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->//定义一个的Dictionary,让它的值进行添加(也可以用Add方法)
Dictionary dic = new Dictionary();
 
//添加两个键为"成绩1","成绩2";并为它们的值赋为0
dic["成绩1"] = 0;
dic["成绩2"] = 0;
 
// 把这两个值分别加1
dic["成绩1"]++;
dic["成绩2"]++;

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。如有错误或未考虑完全的地方,望不吝赐教。


推荐阅读
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 生成对抗式网络GAN及其衍生CGAN、DCGAN、WGAN、LSGAN、BEGAN介绍
    一、GAN原理介绍学习GAN的第一篇论文当然由是IanGoodfellow于2014年发表的GenerativeAdversarialNetworks(论文下载链接arxiv:[h ... [详细]
  • 无线认证设置故障排除方法及注意事项
    本文介绍了解决无线认证设置故障的方法和注意事项,包括检查无线路由器工作状态、关闭手机休眠状态下的网络设置、重启路由器、更改认证类型、恢复出厂设置和手机网络设置等。通过这些方法,可以解决无线认证设置可能出现的问题,确保无线网络正常连接和上网。同时,还提供了一些注意事项,以便用户在进行无线认证设置时能够正确操作。 ... [详细]
  • 本文详细介绍了相机防抖的设置方法和使用技巧,包括索尼防抖设置、VR和Stabilizer档位的选择、机身菜单设置等。同时解释了相机防抖的原理,包括电子防抖和光学防抖的区别,以及它们对画质细节的影响。此外,还提到了一些运动相机的防抖方法,如大疆的Osmo Action的Rock Steady技术。通过本文,你将更好地理解相机防抖的重要性和使用技巧,提高拍摄体验。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
  • 本文介绍了Java的集合及其实现类,包括数据结构、抽象类和具体实现类的关系,详细介绍了List接口及其实现类ArrayList的基本操作和特点。文章通过提供相关参考文档和链接,帮助读者更好地理解和使用Java的集合类。 ... [详细]
  • 本文讨论了前端工程化的准备工作,主要包括性能优化、安全防护和监控等方面需要注意的事项。通过系统的答案,帮助前端开发者更好地进行工程化的准备工作,提升网站的性能、安全性和监控能力。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 如何修改路由器密码?路由器登录密码和无线密码的修改方法
    本文介绍了修改路由器密码的两种方法:一是修改路由器登录口令,需要进入路由器后台进行操作;二是修改无线连接密码,通过进入路由器后台的无线设置和无线安全设置进行修改。详细步骤包括复位处理、登录路由器后台、选择系统工具、填入用户名和用户密码、保存修改等。 ... [详细]
  • 本文介绍了2019年上半年内蒙古计算机软考考试的报名通知和考试时间。考试报名时间为3月1日至3月23日,考试时间为2019年5月25日。考试分为高级、中级和初级三个级别,涵盖了多个专业资格。报名采取网上报名和网上缴费的方式进行,报考人员可登录内蒙古人事考试信息网进行报名。详细内容请点击查看。 ... [详细]
  • 本文介绍了作者在开发过程中遇到的问题,即播放框架内容安全策略设置不起作用的错误。作者通过使用编译时依赖注入的方式解决了这个问题,并分享了解决方案。文章详细描述了问题的出现情况、错误输出内容以及解决方案的具体步骤。如果你也遇到了类似的问题,本文可能对你有一定的参考价值。 ... [详细]
author-avatar
liu100897
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有