在大多数编程语言中,字典比哈希表更受欢迎。这背后的原因是什么?
当前回答
另一个重要的区别是Hashtable是线程安全的。Hashtable具有内置的多读取器/单写入器(MR/SW)线程安全性,这意味着Hashtable允许一个写入器与多个读取器一起使用,而无需锁定。
在Dictionary的情况下,没有线程安全;如果需要线程安全,则必须实现自己的同步。
进一步阐述:
Hashtable通过Synchronized属性提供了一些线程安全性,该属性返回集合周围的线程安全包装。包装器通过在每次添加或删除操作时锁定整个集合来工作。因此,每个试图访问集合的线程都必须等待轮到它获取一个锁。这是不可扩展的,可能会导致大型集合的性能显著下降。此外,该设计没有完全保护免受比赛条件的影响。.NET Framework 2.0集合类(如List<T>、Dictionary<TKey、TValue>等)不提供任何线程同步;当在多个线程上同时添加或删除项时,用户代码必须提供所有同步
如果需要类型安全和线程安全,请在.NETFramework中使用并发集合类。在这里进一步阅读。
另外一个区别是,当我们在字典中添加多个条目时,条目的添加顺序保持不变。当我们从字典中检索条目时,我们将按照插入它们的相同顺序获取记录。而Hashtable不保留插入顺序。
其他回答
根据我使用.NET Reflector所看到的:
[Serializable, ComVisible(true)]
public abstract class DictionaryBase : IDictionary, ICollection, IEnumerable
{
// Fields
private Hashtable hashtable;
// Methods
protected DictionaryBase();
public void Clear();
.
.
.
}
Take note of these lines
// Fields
private Hashtable hashtable;
因此,我们可以确定DictionaryBase在内部使用HashTable。
MSDN上的《使用C#对数据结构进行广泛检查》一文指出,冲突解决策略也存在差异:
Hashtable类使用一种称为rehashing的技术。
Rehashing的工作原理如下:有一组哈希不同的函数,H1。。。Hn,并且当从哈希中插入或检索项时表中,最初使用H1哈希函数。如果这导致如果需要,则尝试H2,然后继续到Hn。
字典使用了一种称为链接的技术。
通过重新散列,在发生冲突时,将重新计算哈希,并尝试与哈希对应的新槽。然而,通过链接,使用辅助数据结构来保存任何碰撞。具体来说,字典中的每个插槽都有一个数组映射到该存储桶的元素。如果发生碰撞冲突元素被添加到桶的列表中。
另一个重要的区别是Hashtable是线程安全的。Hashtable具有内置的多读取器/单写入器(MR/SW)线程安全性,这意味着Hashtable允许一个写入器与多个读取器一起使用,而无需锁定。
在Dictionary的情况下,没有线程安全;如果需要线程安全,则必须实现自己的同步。
进一步阐述:
Hashtable通过Synchronized属性提供了一些线程安全性,该属性返回集合周围的线程安全包装。包装器通过在每次添加或删除操作时锁定整个集合来工作。因此,每个试图访问集合的线程都必须等待轮到它获取一个锁。这是不可扩展的,可能会导致大型集合的性能显著下降。此外,该设计没有完全保护免受比赛条件的影响。.NET Framework 2.0集合类(如List<T>、Dictionary<TKey、TValue>等)不提供任何线程同步;当在多个线程上同时添加或删除项时,用户代码必须提供所有同步
如果需要类型安全和线程安全,请在.NETFramework中使用并发集合类。在这里进一步阅读。
另外一个区别是,当我们在字典中添加多个条目时,条目的添加顺序保持不变。当我们从字典中检索条目时,我们将按照插入它们的相同顺序获取记录。而Hashtable不保留插入顺序。
我能发现的另一个区别是:
我们不能在web服务中使用Dictionary<KT,VT>(泛型)。原因是没有web服务标准支持泛型标准。
从概念上讲,字典是一个哈希表。
如果你的意思是“为什么我们使用Dictionary<TKey,TValue>类而不是Hashtable类?”,那么答案很简单:Dictionary>TKey,TValue>是泛型类型,Hashtable不是。这意味着你可以通过Dictionary<TKey,TValue>获得类型安全性,因为你不能在其中插入任何随机对象,也不必强制转换你取出的值。
有趣的是,.NET Framework中的Dictionary<TKey,TValue>实现是基于Hashtable的,您可以从其源代码中的注释中看出:
通用字典已从Hashtable的源复制
来源
推荐文章
- 不能在lambda表达式中使用ref或out参数
- c# int到字节[]
- 如何跟踪log4net问题
- 将WPF组合框绑定到自定义列表
- foreach vs somlist . foreach (){}
- 为什么try{…}最后{…}好;尝试{…} catch{}坏?
- c# 8用多种情况切换表达式,结果相同
- 在没有事件源注册的情况下写入Windows应用程序事件日志
- 并发HashSet<T>在。net框架?
- 从控制器内获得控制器和动作名称?
- _ViewStart的位置和方式。CSHTML布局文件链接?
- 新建T()
- 如何将枚举绑定到WPF中的组合框控件?
- 拒绝访问该路径
- Visual Studio - Resx文件默认“内部”为“公共”