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


当前回答

人们说字典和哈希表是一样的。

这不一定是真的。哈希表是实现字典的一种方法。这是一个典型的例子,它可能是.NET中Dictionary类中的默认例子,但根据定义,它不是唯一的例子。

你同样可以使用链接列表或搜索树来实现字典,但它并没有那么高效(对于一些高效的度量)。

其他回答

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

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

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

Dictionary<>是泛型类型,因此它是类型安全的。

您可以在HashTable中插入任何值类型,这有时可能会引发异常。但是Dictionary<int>只接受整数值,类似地Dictionary><string>只接受字符串。

因此,最好使用Dictionary<>而不是HashTable。

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

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

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

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

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

哈希表:

键/值将在存储到堆中时转换为对象(装箱)类型。

从堆中读取时,需要将键/值转换为所需的类型。

这些操作成本很高。我们需要尽可能避免装箱/拆箱。

字典:HashTable的泛型变体。

禁止装箱/拆箱。无需转换。

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

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