这一节我们来学习第二种集合,因为它的特性,可以提供一种相当有效率的搜索方法,所以在实际项目中非常实用,它就是哈希表。哈希继承了IDictionary接口,IDictionary接口提供了key(键)/value(值)集合设计模式,这种类集合中的每个一个对象都包含一个与它相对应的key,可以通过所指定的key找到集合中所对应的对象(value值),这个接口最重要之处在于定义了公共属性Item、values、keys,其中Item根据指定的key返回集合中所对应的值,values用来返回集合中所有的对象元素,keys则返回集合中的所以key,现在你们就把key想象成存放值的“索引值”,通过这个“索引值”可以找到值。除了哈希表有这种键值对的访问机制外,下一节我们也将学习到一种SortList 类,它是键/值条目和一个ArrayList集合的组合体,实现了二元搜索,性能更加强大。接下来,我们就来理解一下什么是键值对的访问机制,同时利用实例理解哈希与HashTable类。
哈希提供了一种类似字典的数据结构,原理是通过哈希函数是一个映象,即:将关键字的集合映射到某个地址集合上,它的设置很灵活,只要这个地址集合的大小不超出允许范围即可。将集合中元素的key值经过哈希函数转换成对应表格中的索引值,该类的表格称为哈希表,通过哈希函数的使用,键值对应到一个称为哈希码的值,再通过这个哈希码形成的索引地址,找到指定的对象元素即value值。下面我们来看一下哈希的知识要点:
哈希表是键/值对的集合 ,这些键值对根据键的哈希代码进行组织,根据键可以查找到相应的值。
这个要点我就不再解释了,你们要记住的是,对哈希的操作内部机制实质上都是对键的操作。
键不能为空或重复,value值可以。键、值可以为任意数据类型。
因为是对键的操作,所以就要求key值的唯一性,同时任何数据类型都可以存放在哈希表中,而且对键值对的操作也是严格根据其数据类型进行的。比如key值是整型1和字符串类型的1,所查找的value值的索引地址是不同的,这一点必须严格执行。
动态存放键/值对,容量根据实际需要自动增加。
HashTable类所创建的集合对象,容量也是依据需要而自动增加的,它的扩充会比ArrayList更加科学,不会成倍增长,而是根据加载因子来决定,这个因子决定集合在填充多少元素时,才继续扩充其容量。
定义哈希表对象的语法是Hashtable hstb = new Hashtable( );
常用的属性
hstb.Count哈希表中键值对的元素个数 ,这两种的用法和ArrayList相同,我们着重理解的是下面两个HashTable类的属性:
hstb.keys取得集合中的键值集合; hstb. Values返回相对的数值集合对象。这两个都是根据对象的元素得来的,是只读属性,无法修改它们的结果。
常用方法
增加元素-在增加哈希表元素的时候,有两种方式,第一种是hstb.Add(key,value)一定要键值对的形式同时增加用“,”隔开;第二种是通过键获取值的形式添 加,同时这种格式也可以修改指定的键中的值,然后存储在哈希对象hstb中,格式是hstb[key]=value;应注意键和值的数据类型。
删除元素-删除元素用两种hstb.Clear();全部删除,第二种是根据键删除元素hstb.Remove(key);
查找元素- hstb. Contains(key)、 hstb.ContainsKey(key)查看是否包含指定的键,
hstb.ContainsValue(Value)是否包含指定的值,返回的都是true或false,体现查询结果。
遍历元素-遍历有两种形式,第一种:哈希的元素是一个键值对,DictionaryEntry类型是一个键值对的集合,使用这个类型的对象来进行遍历hstb对象
如: foreach (DictionaryEntry jzd in hstb ) 遍历出的对象是一个哈希的键值对,然后利用jzd .Key取得键 ,jzd .Value取得值。
第二种遍历是遍历出keys或Values的集合的每个键或值,如 foreach( object k in hstb .Keys )或foreach( object v in hstb .Values )
注意:因为键或值的数据类型可以为任意类型,所以遍历出集合后,存放键或值的变量的数据类型最好为object型,此类型包含任何一个类型。
在哈希类中,一定的按照键的数据类型和键值的排列原则,这就决定了无法对元素进行排序,因此我们不能通过特定顺序取得指定的元素。下面我们通过几个例子和结果给大家形象的演示一下哈希表的属性和方法的使用。
2 Console.WriteLine("正在给hstb集合增加元素!请注意键和值的数据类型!");
3 hstb.Add(1, 11); //值的类型是整数型
4 hstb.Add("1", "我的键是字符串1");
5 hstb.Add(5, "我的键是整型5,比你们大,应该先显示");
6 hstb[3] = "我是用获取方式赋值的";
7 Console.WriteLine("hstb集合增加{0}个元素!",hstb .Count);
8
9 Console.WriteLine("使用遍历出键值对变量方法,结果如下:");
10
11 Console.WriteLine("\t键\t值");
12 foreach (DictionaryEntry jzd in hstb)
13 {
14 Console.WriteLine("\t{0}\t{1}", jzd.Key, jzd.Value);
15 }
16
接下来我们接着上面的例子加入以下代码演示一下修改键值为3的元素值,然后利用键集合遍历出键和值。
hstb[3] = "获取方式也可以修改你的值,哈哈!";
Console.WriteLine("使用键集合遍历出键和值");
Console.WriteLine("\t键\t值");
foreach (object k in hstb.Keys)
{
Console.WriteLine("\t{0}\t{1}", k, hstb[k]);
}
遍历出k后,k存放的是元素的键,再通过键获取值。
运行结果对比如下:
看一下 键为3的元素值被修改了,接下来,我们演示按照键删除元素,再使用值集合遍历出元素值,注意:这种遍历是得不到元素键的值的,原因就是哈希代码是按照键进行组织的,我们现在接着在上面的例子中加入如下代码:
通过下面的例子,相信对它的使用你们已经熟悉了,下面我留一道作业题运行结果如图:
这个作业比较简单,学号用键来存放,值存放的是一个变量姓名,正常情况下,值会以一个数组或动态数组的形式存放更多的信息,如:年龄、联系方式等,然后通过Value值中数组的索引查找单个信息,实现修改等操作,同时这种用法也是实际项目中的常用做法,比如网上商城,增加一条商品信息,常会采用哈希表来实现功能。下一节我们要来学习二元搜索和sortlist类。