一、介绍
哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做哈希函数,存放记录的数组叫做哈希表。
二、使用
(1)某些数据会被高频率查询
(2)数据量大
(3)查询字段包含字符串类型
(4)数据类型不唯一
三、使用方法
哈希表需要使用的namespace:
using System.Collections.Generic;
using System.Collections;
(1) 基本操作
//添加一个keyvalue键值对:
HashtableObject.Add(key,value);
//移除某个keyvalue键值对:
HashtableObject.Remove(key);
//移除所有元素:
HashtableObject.Clear();
// 判断是否包含特定键key:
HashtableObject.Contains(key);
(2) 控制台程序例子
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(); //移除所有元素
}
(3) 错误处理
当获取哈希表中数据时,如果类型声明的不对,会出现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型");
}
}
}
(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) 排序
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);
sw.Restart();
for (int i = 0; i < countNum; i++)
{
dictionary.Add(i.ToString(), i);
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
sw.Restart();
for (int i = 0; i < countNum; i++)
{
hashtable.ContainsKey(i.ToString());
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
sw.Restart();
for (int i = 0; i < countNum; i++)
{
dictionary.ContainsKey(i.ToString());
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
由此可见,添加数据时Hashtable快。频繁调用数据时Dictionary快。
Dictionary<K,V>是泛型的,当K或V是值类型时,其速度远远超过Hashtable。
四、实例
在机房合作中小编简单运用到的是数据库字段转换。
为什么呢? 组合查询这个功能是用到了设计模式,将相同的代码拿出来放在父窗体中,而子窗体中写的是自己的方法。所以,这样会导致了方法的参数问题,不同方法,不同的参数。运用最简单粗暴的方法,直接在combox中item-add 添加字段,并写一个select语句对其进行判断传给B层所需要的数据库字段名称。而这样效率不高,所以,使用哈希表就可以完美解决。
Hashtable haField = new Hashtable();//定义处理字段名转换的hashtable
//使用哈希表进行数据库字段进行转换
//数据库中的字段对应相应的中文
//变量赋多值
//放到comfield字段中
string[] strFieldName = new string[] { "卡号", "学号", "姓名", " 性别", "院系", "年级", "班级" };
string[] strFieldValue = new string[] { "cardNo", "studentNo", "studentName", "sex", "department", "Class", "grade" };
//'中文为key,英文为value添加到hashtable
for (int i = 0; i < strFieldName.Length - 1; i++)
{
comField1.Items.Add(strFieldName[i]);
comField2.Items.Add(strFieldName[i]);
comField3.Items.Add(strFieldName[i]);
haField.Add(strFieldName[i], strFieldValue[i]);
}
五、小结
- 学而不思则罔,思而不学则殆。 在发现的过程去学习,在学习的过程中去实践学习。学习实践,在学习的过程不断的去深入。
- 扩展知识,得到提升。
- 基础很重要,总结更重要。