在大多数编程语言中,字典比哈希表更受欢迎。这背后的原因是什么?


当前回答

字典:

如果我们试图找到不存在的键,它将返回/抛出异常。它比哈希表更快,因为没有装箱和拆箱。只有公共静态成员是线程安全的。字典是一种通用类型,这意味着我们可以将它与任何数据类型一起使用(创建时,必须为键和值指定数据类型)。示例:Dictionary<string,string><NameOfDictionaryVar>=新字典<string,string>();字典是Hashtable的类型安全实现,键和值是强类型的。

哈希表:

如果我们试图找到一个不存在的键,它将返回null。它比字典慢,因为它需要装箱和拆箱。Hashtable中的所有成员都是线程安全的,Hashtable不是泛型类型,哈希表是松散类型的数据结构,我们可以添加任何类型的键和值。

其他回答

MSDN上的《使用C#对数据结构进行广泛检查》一文指出,冲突解决策略也存在差异:

Hashtable类使用一种称为rehashing的技术。

Rehashing的工作原理如下:有一组哈希不同的函数,H1。。。Hn,并且当从哈希中插入或检索项时表中,最初使用H1哈希函数。如果这导致如果需要,则尝试H2,然后继续到Hn。

字典使用了一种称为链接的技术。

通过重新散列,在发生冲突时,将重新计算哈希,并尝试与哈希对应的新槽。然而,通过链接,使用辅助数据结构来保存任何碰撞。具体来说,字典中的每个插槽都有一个数组映射到该存储桶的元素。如果发生碰撞冲突元素被添加到桶的列表中。

Hashtable对象由包含集合元素的桶组成。bucket是Hashtable中元素的虚拟子组,这使得搜索和检索比大多数集合更容易和更快。

Dictionary类具有与Hashtable类相同的功能。对于值类型,特定类型(而不是Object)的字典比Hashtable具有更好的性能,因为Hashtable的元素属于Object类型,因此,如果存储或检索值类型,通常会进行装箱和取消装箱。

进一步阅读:哈希表和字典集合类型

字典:

如果我们试图找到不存在的键,它将返回/抛出异常。它比哈希表更快,因为没有装箱和拆箱。只有公共静态成员是线程安全的。字典是一种通用类型,这意味着我们可以将它与任何数据类型一起使用(创建时,必须为键和值指定数据类型)。示例:Dictionary<string,string><NameOfDictionaryVar>=新字典<string,string>();字典是Hashtable的类型安全实现,键和值是强类型的。

哈希表:

如果我们试图找到一个不存在的键,它将返回null。它比字典慢,因为它需要装箱和拆箱。Hashtable中的所有成员都是线程安全的,Hashtable不是泛型类型,哈希表是松散类型的数据结构,我们可以添加任何类型的键和值。

自.NET Framework 3.5以来,还有一个HashSet<T>,它提供了字典<TKey,TValue>的所有优点,如果您只需要键而不需要值。

因此,如果您使用Dictionary<MyType,object>并始终将值设置为null以模拟类型安全哈希表,您可能应该考虑切换到HashSet<T>。

因为Dictionary是一个泛型类(Dictionary<TKey,TValue>),所以访问其内容是类型安全的(即,不需要像Hashtable那样从Object转换)。

比较

var customers = new Dictionary<string, Customer>();
...
Customer customer = customers["Ali G"];

to

var customers = new Hashtable();
...
Customer customer = customers["Ali G"] as Customer;

然而,Dictionary在内部实现为哈希表,因此技术上它的工作方式相同。