C#中哈希表(HashTable)用法实例详解(添加/移除/判断/遍历/排序等)

本文实例讲述了C#中哈希表(HashTable)用法。分享给大家供大家参考,具体如下:

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<string, int> dictionary = new Dictionary<string, int>();
int countNum = 1000000;
sw.Start();
for (int i = 0; i < countNum; i++)
{
  hashtable.Add(i.ToString(), i);
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds); //输出: 744
sw.Restart();
for (int i = 0; i < countNum; i++)
{
  dictionary.Add(i.ToString(), i);
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds); //输出: 489
sw.Restart();
for (int i = 0; i < countNum; i++)
{
  hashtable.ContainsKey(i.ToString());
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds); //输出: 245
sw.Restart();
for (int i = 0; i < countNum; i++)
{
  dictionary.ContainsKey(i.ToString());
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds); //输出: 192

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

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

更多关于C#相关内容感兴趣的读者可查看本站专题:《C#遍历算法与技巧总结》、《C#程序设计之线程使用技巧总结》、《C#操作Excel技巧总结》、《C#中XML文件操作技巧汇总》、《C#常见控件用法教程》、《WinForm控件用法总结》、《C#数据结构与算法教程》、《C#数组操作技巧总结》及《C#面向对象程序设计入门教程》

希望本文所述对大家C#程序设计有所帮助。

(0)

相关推荐

  • C#实现冒泡排序算法的代码示例

    1.原理:从数组的第一个位置开始两两比较array[index]和array[index+1],如果array[index]大于array[index+1]则交换array[index]和array[index+1]的位置,止到数组结束; 从数组的第一个位置开始,重复上面的动作,止到数组长度减一个位置结束; 从数组的第一个位置开始,重复上面的动作,止到数组长度减二个位置结束; .... 2.时间复杂度:O(N²),进行了(n-1)*(n-2)....=n*(n-1)/2次比较和约比较次数一半的交

  • C#插入法排序算法实例分析

    本文实例讲述了C#插入法排序算法.分享给大家供大家参考.具体如下: public static void InsertSort (int[] list) { for (int i = 1; i < list.Length; i++) { int Temp = list [i]; int j = i - 1; while (j > = 0 && list [j] > Temp) { list [j + 1] = list [j]; j-; } list [j + 1] =

  • C#递归算法之快速排序

    上两片第归算法学习: 1)递归算法之分而治之策略 2)递归算法之归并排序 上一篇学习中介绍了了递归算法在排序中的一个应用:归并排序,在排序算法中还有一种算法用到了递归,那就是快速排序,快速排序也是一种利用了分而治之策略的算法,它由C.A.R发明,它依据中心元素的值,利用一系列递归调用将数据表划分成越来越小的子表.在每一步调用中,经过多次的交换,最终为中心元素找到最终的位置.与归并算法不同,快速排序是就地排序,而归并排序需要把元素在临时向量中拷贝,下面通过对以下向量进行排序来理解和加深快速排序算法

  • 逐步讲解快速排序算法及C#版的实现示例

    算法思想 快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序.它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod). 该方法的基本思想是: 1.先从数列中取出一个数作为基准数. 2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边. 3.再对左右区间重复第二步,直到各区间只有一个数. 虽然快速排序称为分治法,但分治法这三个字显然无法很好的概括快速排序的全部步骤.因此我的对快速排序作了进一步的说明:挖坑填数+分治法:

  • C#堆排序实现方法

    本文实例讲述了C#堆排序实现方法.分享给大家供大家参考.具体如下: private static void Adjust (int[] list, int i, int m) { int Temp = list[i]; int j = i * 2 + 1; while (j <= m) { //more children if(j < m) if(list[j] < list[j + 1]) j = j + 1; //compare roots and the older childre

  • C#中使用基数排序算法对字符串进行排序的示例

    开始之前 假设最长字符串的长度是L,以L作为输入的长度, 然后假定所有的字符串都"补齐"到此长度,这个补齐只是逻辑上的,我们可以假想有一种"空字符", 它小于任何其它字符,用此字符补齐所有长度不足的字符串.例如:最长的字符串长度为9,有一个字符串A长度为6, 那么当比较第7位字符的时候,我们让A[7]为"空字符". 如果要包含所有的字符似乎并不容易,我们先定义一个字符集, 待排序字符串中的所有字符都包含在这个字符集里 //字符集 private

  • C#选择法排序实例分析

    本文实例讲述了C#选择法排序实现方法.分享给大家供大家参考.具体实现方法如下: public int[] SelectionSort(int[] arr) { //1. Find min //2. Swap it with first element //3. Repeat starting from secong position onwards. int _min = 0; for (int i = 0; i < arr.Length; i++) { _min = i; for (int j

  • 关于C#中排序函数的总结

    sort 函数对数组中的数据进行升序排序,(其中,sort函数有很多重载的形式,这里不再一一的说明) Reverse函数对数组中的数据进行降序排序, static void Main(string[] args) { // sort ,Reverse 排序的应用举例 int[] intArr = { 1,4,2,3,99,34,22,16,8,100}; Console.WriteLine("原数组为:"); for (int i = 0; i < intArr.Length;

  • C#递归算法之归并排序

    归并排序是利用递归和分而治之的技术将数据序列划分成为越来越小的半子表,再对半子表排序,最后再用递归步骤将排好序的半子表合并成为越来越大的有序序列,归并排序包括两个步骤,分别为: 1)划分子表 2)合并半子表 首先我们来讨论归并算法,归并算法将一系列数据放到一个向量中,索引范围为[first,last],这个序列由两个排好序的子表构成,以索引终点(mid)为分界线,以下面一个序列为例 7,10,19,25,12,17,21,30,48 这样的一个序列中,分为两个子序列 7,10,19,25  和

  • C#中哈希表(HashTable)用法实例详解(添加/移除/判断/遍历/排序等)

    本文实例讲述了C#中哈希表(HashTable)用法.分享给大家供大家参考,具体如下: 1.  哈希表(HashTable)简述 在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似keyvalue的键值对,其中key通常可用来快速查找,同时key是区分大小写:value用于存储对应于key的值.Hashtable中keyvalue键值对均为object类型,所以Hashtable可以支持任何类型的keyvalue键

  • Angular中$cacheFactory的作用和用法实例详解

    先说下缓存: 一个缓存就是一个组件,它可以透明地储存数据,以便以后可以更快地服务于请求.多次重复地获取资源可能会导致数据重复,消耗时间.因此缓存适用于变化性不大的一些数据,缓存能够服务的请求越多,整体系统性能就能提升越多. $cacheFactory介绍: $cacheFactory是一个为Angular服务生产缓存对象的服务.要创建一个缓存对象,可以使用$cacheFactory通过一个ID和capacity.其中,ID是一个缓存对象的名称,capacity则是描述缓存键值对的最大数量. 1.

  • ES6中Array.copyWithin()函数的用法实例详解

    ES6为Array增加了copyWithin函数,用于操作当前数组自身,用来把某些个位置的元素复制并覆盖到其他位置上去. Array.prototype.copyWithin(target, start = 0, end = this.length) 该函数有三个参数. target:目的起始位置. start:复制源的起始位置,可以省略,可以是负数. end:复制源的结束位置,可以省略,可以是负数,实际结束位置是end-1. 例: 把第3个元素(从0开始)到第5个元素,复制并覆盖到以第1个位置

  • Java中的接口和抽象类用法实例详解

    本文实例讲述了Java中的接口和抽象类用法.分享给大家供大家参考,具体如下: 在面向对象的概念中,我们知道所有的对象都是通过类来描绘的,但是并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类. 抽象类往往用来表征我们在对问题领域进行分析. 设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象,我们不能把它们实例化(拿不出一个具体的东西)所以称之为抽象. 比如:我们要描述"水果",它就是一个抽象,它有质量.体积等

  • Python中sys模块功能与用法实例详解

    本文实例讲述了Python中sys模块功能与用法.分享给大家供大家参考,具体如下: sys-系统特定的参数和功能 该模块提供对解释器使用或维护的一些变量的访问,以及与解释器强烈交互的函数.它始终可用. sys.argv 传递给Python脚本的命令行参数列表.argv[0]是脚本名称(依赖于操作系统,无论这是否是完整路径名).如果使用-c解释器的命令行选项执行命令,argv[0]则将其设置为字符串'-c'.如果没有脚本名称传递给Python解释器,argv[0]则为空字符串. 要循环标准输入或命

  • jQuery中attr()与prop()函数用法实例详解(附用法区别)

    本文实例讲述了jQuery中attr()与prop()函数用法.分享给大家供大家参考,具体如下: 一.jQuery的attr()方法 jquery中用attr()方法来获取和设置元素属性,attr是attribute(属性)的缩写,在jQuery DOM操作中会经常用到attr(),attr()有4个表达式. 1. attr(属性名) //获取属性的值(取得第一个匹配元素的属性值.通过这个方法可以方便地从第一个匹配元素中获取一个属性的值.如果元素没有相应属性,则返回 undefined ) 2.

  • javascript中2个感叹号的用法实例详解

    在javascript代码中经常会见到!!的情况,本文即以实例形式较为深入的分析javascript中2个感叹号的用法.分享给大家供大家参考之用.具体分析如下: javascript中的!!是逻辑"非非",即是在逻辑"非"的基础上再"非"一次.通过!或!!可以将很多类型转换成bool类型,再做其它判断. 一.应用场景:判断一个对象是否存在 假设有这样一个json对象: { color: "#E3E3E3", "fon

  • Android中AlertDialog各种对话框的用法实例详解

    目标效果: 程序运行,显示图一的几个按钮,点击按钮分别显示图二到图六的对话框,点击对话框的某一项或者按钮,也会显示相应的吐司输出. 1.activity_main.xml页面存放五个按钮. activity_main.xml页面: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools&

  • PHP中__get()和__set()的用法实例详解

    php面向对象_get(),_set()的用法 一般来说,总是把类的属性定义为private,这更符合现实的逻辑.但是,对属性的读取和赋值操作是非常频繁的,因此在PHP5中,预定义了两个函数"__get()"和"__set()"来获取和赋值其属性.类似于java中的javabean的操作,使用的方法也类似,只是不需要像javabean中那样,对每个字段进行set和get的操作.只需要加上两个魔术方法即可.即私有成员的设值和取值的操作.在PHP5中给我们提供了专门为属

  • PHP中的switch语句的用法实例详解

    switch是一个开关语句,那么很多朋友都只知道简单的switch开关语句的用法了,下面一聚教程小编就为各位详细的介绍一下switch用法例子吧. 只所以称为"高级"用法,是因为我连switch的最基础的用法都还没有掌握,so,接下来讲的其实还是它的基础用法! switch 语句和具有同样表达式的一系列的 IF 语句相似.很多场合下需要把同一个变量(或表达式)与很多不同的值比较,并根据它等于哪个值来执行不同的代码.这正是 switch 语句的用途. 注意: 注意和其它语言不同,cont

随机推荐