关于.NET中Hashtable的遍历及其存储方式:

先看看代码——

            Hashtable Specialor = new Hashtable();
            Specialor.Add(1, 1);
            Specialor.Add(2, 2);
            Specialor.Add(3,3);
            Specialor.Add(4, 4);
            Specialor.Add(5,5);
            Specialor.Add(6,6);
            Specialor.Add(7, 7);
            Specialor.Add(8,8);
            Specialor.Add(9, 9);
            Specialor.Add(10,10);
  
           
            IDictionaryEnumerator info = Specialor.GetEnumerator();
            while(info.MoveNext()){
               Response.Write(info.Values);
            }

  输出的结果竟然是:10 9 8 7 6 5 4 3 2 1

   这条代码段,说明当我们按顺序将值放入Hashtable对象中,然后再按顺序取值,却发现它居然的输出是倒序的,好像把我们的数据进行了倒序排列。
这是什么原因呢?我们来看看Hashtable的存储数据的方式及有用的资料:
  Hashtable是一种使用非常频繁的基础集合类型。需要理解影响Hashtable的效率有两个因素:一是散列码(GetHashCode方法),二是等值比较(Equals方法)。Hashtable首先使用键的散列码将对象分布到不同的存储桶中,随后在该特定的存储桶中使用键的Equals方法进行查找。
 良好的散列码是第一位的因素,最理想的情况是每个不同的键都有不同的散列码。Equals方法也很重要,因为散列只需要做一次,而存储桶中查找键可能需要做多次。从实际经验看,使用Hashtable时,Equals方法的消耗一般会占到一半以上。

System.Object类提供了默认的GetHashCode实现,使用对象在内存中的地址作为散列码。我们遇到过一个用Hashtable来缓存对象的例子,每次根据传递的OQL表达式构造出一个ExpressionList对象,再调用QueryCompiler的方法编译得到CompiledQuery对象。以ExpressionList对象和CompiledQuery对象作为键值对存储到Hashtable中。ExpressionList对象没有重载GetHashCode实现,其超类ArrayList也没有,这样最后用的就是System.Object类的GetHashCode实现。由于ExpressionList对象会每次构造,因此它的HashCode每次都不同,所以这个CompiledQueryCache根本就没有起到预想的作用。这个小小的疏漏带来了重大的性能问题,由于解析OQL表达式频繁发生,导致CompiledQueryCache不断增长,造成服务器内存泄漏!解决这个问题的最简单方法就是提供一个常量实现,例如让散列码为常量0。虽然这会导致所有对象汇聚到同一个存储桶中,效率不高,但至少可以解决掉内存泄漏问题。当然,最终还是会实现一个高效的GetHashCode方法的。
 以上介绍这些Hashtable机理,主要是希望大家理解:如果使用Hashtable,你应该检查一下对象是否提供了适当的GetHashCode和Equals方法实现。否则,有可能出现效率不高或者与预期行为不符的情况。

  散列表,又称为哈希表,是线性表中一种重要的存储方式和检索方法。在散列表中,可以对节点进行快速检索。散列在算法的基本思想是:由结点的关键码值决定结点的存储地址,即以关键码值k为自变量,通过一定的函数关系h(称为散列函数),计算出对应的函数值h(k)。将这个值解释为结点的存储地址,将结点存入该地址中。检索时,根据要检索的关键码值,用同样的散列函数计算出地址,然后,到相应的地址中去获取要找的结点数据。因此,图列表有一个重要特征:平均检索的长度不直接依赖于表中元素的数量。
     散列表最重要的一个指标是负载因子,即散列表中结点数目与表中能容纳的总结点数的比值。它描述了散列表的饱和程度,负载因子越接近1.0,内存的使用效率越高,元素的寻找时间越长;同样,负载因子越接近0.0,元素的寻找时间越短,但内存的浪费越大。Hashtable类缺省的负载因子为0.75。散列表的装载因子实际上依赖于散列表的用法和优先级是否基于性能或内存效率。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值