我试图弄清楚什么时候以及为什么要使用字典或哈希表。我在这里做了一些搜索,发现人们在谈论Dictionary的一般优势,我完全同意这一点,它带来了装箱和拆箱的优势,从而获得了轻微的性能增益。

但我也读过字典不会总是按照插入的顺序返回对象,事情是有序的。就像哈希表一样。据我所知,这导致哈希表在某些情况下要快得多。

我的问题是,这些情况可能是什么?我上面的假设是错的吗?你会在什么情况下选择一个而不是另一个,(是的,最后一个有点模棱两可)。


当前回答

System.Collections.Generic。Dictionary<TKey, TValue>和System.Collections.Hashtable类都在内部维护哈希表数据结构。没有一个能保证保持物品的顺序。

撇开装箱/开箱问题不谈,大多数情况下,它们应该具有非常相似的性能。

它们之间主要的结构区别在于Dictionary依赖于链接(为每个哈希表桶维护一个项目列表)来解决冲突,而Hashtable使用重哈希来解决冲突(当发生冲突时,尝试另一个哈希函数来将键映射到一个桶)。

如果你的目标是。net Framework 2.0+,使用哈希表类没有什么好处。它被Dictionary<TKey, TValue>有效地废弃了。

其他回答

另一个重要的区别是Hashtable类型同时支持无锁的多个读取器和单个写入器,而Dictionary则不支持。

两者实际上是同一个类(您可以查看反汇编)。HashTable是在。net有泛型之前创建的。Dictionary是一个泛型类,可以为您提供强大的类型优势。我永远不会使用哈希表,因为字典不需要你使用。

另一个重要的区别是Hashtable是线程安全的。Hashtable内置了多读取器/单写入器(MR/SW)线程安全性,这意味着Hashtable允许一个写入器和多个读取器一起使用而不需要锁定。在Dictionary的情况下,没有线程安全,如果你需要线程安全,你必须实现自己的同步。

进一步说明:

Hashtable, provide some thread-safety through the Synchronized property, which returns a thread-safe wrapper around the collection. The wrapper works by locking the entire collection on every add or remove operation. Therefore, each thread that is attempting to access the collection must wait for its turn to take the one lock. This is not scalable and can cause significant performance degradation for large collections. Also, the design is not completely protected from race conditions. The .NET Framework 2.0 collection classes like List<T>, Dictionary<TKey, TValue>, etc do not provide any thread synchronization; user code must provide all synchronization when items are added or removed on multiple threads concurrently If you need type safety as well thread safety, use concurrent collections classes in the .NET Framework. Further reading here.

字典比哈希表快,因为字典是泛型强类型。哈希表比较慢,因为它将对象作为数据类型,导致装箱和拆箱。

System.Collections.Generic。Dictionary<TKey, TValue>和System.Collections.Hashtable类都在内部维护哈希表数据结构。没有一个能保证保持物品的顺序。

撇开装箱/开箱问题不谈,大多数情况下,它们应该具有非常相似的性能。

它们之间主要的结构区别在于Dictionary依赖于链接(为每个哈希表桶维护一个项目列表)来解决冲突,而Hashtable使用重哈希来解决冲突(当发生冲突时,尝试另一个哈希函数来将键映射到一个桶)。

如果你的目标是。net Framework 2.0+,使用哈希表类没有什么好处。它被Dictionary<TKey, TValue>有效地废弃了。