我想大家对Hashtable很熟悉,平时在工作中使用的也是比较多的,现在都是3.5了,Dictionary 的出现已经可以替代Hashtable,但是我还是想对这个Net框架使用较多的对象(举个例子:Net的CLR处理一个程序集的字符串就是采用HashTable存储在System Domain)讲解一下,因为很多新的技术都是建立在老的技术和思想上的。
在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似key/value的键值对,其中key通常可用来快速查找,同时key是区分大小写;value用于存储对应于key的值。Hashtable中key/value键值对均为 object类型,所以Hashtable可以支持任何类型的key/value键值对.
例子
先不做解释,看看结果。
在我没有给出自定义类MyTest和cuskey的时候,如果你能猜测出MyTest和cuskey大概代码以及为什么的话,你可以省略
下面的这段内容,^_^.下面给出MyTest和cuskey的代码。
好了,当大家看完这两个自定义的类后,我想很大部分人能通过这两个类的区别可以判断出为什么上面的显示结果会是这样的,下面我俩讲解一下。
MyTest和cuskey的最大的区别就在于MyTest重写了GetHashCode()方法,而cuskey没有重写GetHashCode()方法,我们都知道net的类型最后都是要继承Object类了,也就是说cuskey是使用Object的GetHashCode()方法,它的每个实例的hashcode的算法都是继承自Object,而MyTest重写了GetHashCode()方法,因此MyTest的每个实例的hashcode的算法都是来自重写后的算法。
如上所说,cuskey的每个实例的hashcode是不一样的(Object的GetHashCode()所采用的算法大家有兴趣可以看看),而MyTest的每个实例的hashcode的算法是依赖其成员keyNumber的值,因此只要keyNumber的值相同,我们就认为其hashcode相同。以上我们对这两个自定义的类进行分析,下面我们回到HashTable上。
最开始我们说HashTable用于处理和表现类似key/value的键值对,Hashtable 对象由包含集合元素的存储桶组成。存储桶是 Hashtable 中各元素的虚拟子组,与大多数集合中进行的搜索和检索相比,存储桶可令搜索和检索更为便捷。每一存储桶都与一个哈希代码关联,该哈希代码是使用哈希函数生成的并基于该元素的键。哈希函数是基于键返回数值哈希代码的算法。键是正被存储的对象的某一属性的值。哈希函数必须始终为相同的键返回相同的哈希代码。Hashtable 中用作元素的每一对象必须能够使用GetHashCode()方法的实现为其自身生成哈希代码。在将一个对象添加到 HashTable时,它被存储在存储桶中,该存储桶与匹配该对象的哈希代码的哈希代码关联。在 HashTable内搜索一个值时,将为该值生成哈希代码,并且搜索与该哈希代码关联的存储桶。我们这里MyTest和cuskey的GetHashCode()方法的实现原理不同,直接导致查找的结果不同。
这样上面的例子就不难解释了,注意key4的那两句运行的话是回报错的哦,应该很简单,就是已经包含这样的key。
HashTable是个很重要的数据结构,里面哈希函数的实现是最重要的。大家有时间可以研究一下,参考《数据结构》。
2 ht.Add(new cuskey(m), m);
3/*[{Collections.cuskey}]:1 [{Collections.cuskey}]: 4 [{Collections.cuskey}]:2 [{Collections.cuskey}]:3 [{Collections.cuskey}]: 0
4*/
看看上面的代码,注释部分就是存储在HashTable的顺序,为什么与insert的顺序不同呢?待续。。。