dictionary的使用.net

转自Arturya,csdn,供自己参考

http://blog.csdn.net/arturya/archive/2006/08/19/1096142.aspx

[文档最后修正时间: Aug 19, 2006, by Arturya]

下面我们介绍一下 2.0 新推出的 System.Collections.Generic.Dictionary<K, V> 类型 (以下简称 Dictionary).

Dictionary 的用法与 Hashtable 差不多, f(K) 也采用相同的取模算法, 但其余内部结构无论同 Hashtable 还是 HashMap 都有很大区别. 体现在:
[1] Dictionary 没有 Load Factor 变量, 或可理解为 Load Factor = 1, 插入数据可以最大限度填满容量空间.
[2] 大体上, Dictionary 内的元素有按照先后插入顺序排列的特性. 区别于 Hashtable 及 HashMap 的离散型.

Dictionary 内部拥有两列数组, 姑且成为 "状态串" 和 "数据串", 数据串按顺序接受插入的数据并加以封装 (封装了一个 next 指针, 方便今后装链), 状态串以 f(K) 为索引, 存放 f(K) 到 K 在数据串内的位置映射. 查找时先访问状态串找 f(K), 然后根据映射关系找到数据串中的实际数据. 当有多个 f(K) 重复时, 状态串里面保留第一个 f(K), 在数据串内对冲突的数据建立链关系.

由图我们可以看出, 数据串忠实按照 K1, K2, K3 ... 的插入顺序排列, 直至排满数据串, 这个过程中自然不会发生冲突, 冲突只出现在状态串中, 同时, 发生冲突时并不需探测空位和挪动数据本身, 只需将冲突的数据链在一起即可.

Dictionary 默认初始大小为 3, 扩容方式和 Hashtable 一样, 为不小于当前容量的 2 倍的一个质数. 在速度方面, Dictionary 读取快于 Hashtable, 但不如用 C# 自写的链地址法的哈希表, 写入要慢于 Hashtable, 但快于链地址法的哈希表. 考虑到 Dictionary 隐含的装填因子为  1, 可以最大限度利用空间, 是一种以速度换空间的做法, 这个结果是可以接受的.

由于 Hashtable 和 Dictionary 同时存在, 在使用场景上必然存在选择性, 并不任何时刻都能相互替代.
[1] 单线程程序中推荐使用 Dictionary, 有泛型优势, 且读取速度较快, 容量利用更充分.
[2] 多线程程序中推荐使用 Hashtable, 默认的 Hashtable 允许单线程写入, 多线程读取, 对 Hashtable 进一步调用 Synchronized() 方法可以获得完全线程安全的类型. 而 Dictionary 非线程安全, 必须人为使用 lock 语句进行保护, 效率大减.
[3] Dictionary 有按插入顺序排列数据的特性 (注: 但当调用 Remove() 删除过节点后顺序被打乱), 因此在需要体现顺序的情境中使用 Dictionary 能获得一定方便.

以上分别谈到了  Hashtable, HashMap 和 Dictionary 三种类型, 介绍告一段落, 下面增加一些不成熟的观点:

[1] 三种哈希表均允许任意 object 做关键字, 但实际使用中我们一般只用 string 做键值, 对 string 做 HashOf(string) 处理比较单纯, 速度较快, 而对 object 取 HashOf(object) 则情况复杂. 若想进一步提高速度, 可以考虑自定义一个只允许 string 作为关键字的哈希表.

[2] Java HashMap 由于 f(K) 取与运算的特性, 每次扩容必须是 2 倍, 没有价钱可讲. 但 .NET Hashtable 和  Dictionary 的容量理论上只要求是质数, 新容量不一定要达到旧容量的 2 倍以上, 因而想进一步提高内存利用率, 可以考虑重写 Resize() 方法, 使得每次扩容变成稍大一点的质数即可. 当然这样一来插入效率会降低, 自行取舍.

[3] 对 Hashtable  初始化时直接指定 capacity 是个好主意, 减少了 Resize() 的次数, 降低开销.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值