当前位置:  开发笔记 > 编程语言 > 正文

为什么Dictionary优先于Hashtable?

如何解决《为什么Dictionary优先于Hashtable?》经验,为你挑选了17个好方法。

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



1> Michael Mads..:

对于它的价值,一个字典(概念)的哈希表.

如果你的意思是"为什么我们使用Dictionary类而不是Hashtable类?",那么这是一个简单的答案:Dictionary是泛型类型,Hashtable不是.这意味着您可以获得类型安全性Dictionary,因为您无法在其中插入任何随机对象,并且您不必强制转换所取出的值.

有趣的是,Dictionary.NET Framework中的实现是基于Hashtable,正如您可以从其源代码中的注释中看出的那样:

通用词典是从Hashtable的源代码复制而来的

资源


并且通用集合也快得多,因为没有装箱/拆箱
Hashtable使用Object在内部保存东西(只有非通用的方式),所以它也必须使用box/unbox.
@BrianJ:`HashTable`(类)和`Dictionary`(类)都是哈希表(概念),但是`HashTable`不是`Dictionary`,也不是`Dictionary`和`HashTable`.它们以非常相似的方式使用,并且`Dictionary `可以以与`HashTable`相同的无类型方式运行,但它们不直接共享任何代码(尽管部分可能非常实现)类似的时尚).
@BrianJ:"哈希表"(两个词)是这种结构的计算机科学术语; 字典是一种特定的实现.HashTable大致对应于Dictionary (虽然接口略有不同),但两者都是哈希表概念的实现.当然,只是为了进一步混淆问题,有些语言将其哈希表称为"字典"(例如Python) - 但正确的CS术语仍然是哈希表.
不确定具有上述语句的Hashtable,但对于ArrayList vs List ,它是真的
@BrianJ"如果Dictionary是通用的,那么说哈希表是字典会不会更准确?" - 不,因为"泛型"在编程语言中具有特定含义,与英语术语没什么关系."通用"类或方法是具有一个或多个类型参数的类或方法.
@MichealMadsen,我认为造成混淆的原因是,在C#之外还使用了[字典](http://en.wikipedia.org/w/index.php?title=Dictionary_(data_structure)&redirect=no)一词。作为[抽象数据类型](http://en.wikipedia.org/wiki/Abstract_data_type),“哈希表”是具有特定运行时间的解决方案。另外,[generic](https://www.google.nl/search?q=generic)也具有C#以外的含义,因此,如果您不了解C#,则“通用字典”可以解释为抽象数据结构体。

2> Marcel Toth..:

Dictionary<<< >>> Hashtable差异:

通用 <<< >>> 非通用

需要自己的线程同步 <<< >>> 通过方法提供线程安全版本Synchronized()

枚举项目:KeyValuePair<<< >>>枚举项目:DictionaryEntry

较新(> .NET 2.0)<<< >>>较旧(自.NET 1.0起)

System.Collections.Generic <<< >>>在System.Collections中

请求不存在的键抛出异常 <<< >>>对不存在的键的请求返回null

潜在位更快值类型 <<< >>> 有点慢(需要装箱/拆箱)值类型

Dictionary/ Hashtable相似之处:

两者都是内部哈希表 ==根据键快速访问多项数据

两者都需要不可变和唯一的密钥

两者的关键都需要自己的GetHashCode()方法

类似的 .NET集合(候选使用而不是Dictionary和Hashtable):

ConcurrentDictionary- 线程安全(可以同时从多个线程安全地访问)

HybridDictionary- 优化的性能(少数项目和许多项目)

OrderedDictionary- 可以通过int索引访问值(按添加项目的顺序)

SortedDictionary- 项目自动排序

StringDictionary- 强类型和优化字符串


我们可以将concurrentDictionary(在.NET 4.0中)用于线程安全.
@ Guillaume86,这就是你使用TryGetValue的原因http://msdn.microsoft.com/en-us/library/bb347013.aspx
当您使用默认构造函数时,“ StringDictionary”的+1 ... btw“ StringDictionary”与“ Dictionary <string,string>”不同。
很棒的解释,你真的很好,你也列出了相似之处,以减少可能出现在你脑海中的问题

3> gius..:

因为Dictionary是一个泛型类(Dictionary),所以访问它的内容是类型安全的(即你不需要Object像使用a一样进行转换Hashtable).

相比

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

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

但是,Dictionary在内部实现为哈希表,因此从技术上讲它的工作方式相同.



4> 小智..:

仅供参考:在.NET中,Hashtable线程可以安全地供多个读取器线程和单个写入线程使用,而在Dictionary公共静态成员中是线程安全的,但不保证任何实例成员都是线程安全的.

因此,我们不得不改变所有字典Hashtable.


.Net 4.0添加了`ConcurrentDictionary`类,其中所有公共/受保护的方法都是线程安全的.如果您不需要支持旧版平台,则可以在多线程代码中替换`Hashtable`:http://msdn.microsoft.com/en-us/library/dd287191.aspx
乐趣.Dictionary 源代码看起来更清晰,更快.使用Dictionary并实现自己的同步可能更好.如果Dictionary绝对需要是最新的,那么你只需要同步访问Dictionary的读/写方法.这将是很多锁定,但它是正确的.
或者,如果您的读取不必绝对是最新的,则可以将字典视为不可变.然后,您可以获取对Dictionary的引用,并通过不同步读取来获得性能(因为它是不可变的并且本质上是线程安全的).要更新它,您需要在后台构建一个完整的Dictionary更新副本,然后只需使用Interlocked.CompareExchange交换引用(假设一个写入线程;多个写入线程需要同步更新).
我记得在没有从表中删除信息的情况下,HashTable只是读写器线程安全的.如果读者在删除不同的项目时要求表中的项目,并且读者将在该项目的多个位置查找,则可能在读者正在搜索时可能会移动该项目从未经检查的地方到有检查的地方,从而导致该项目不存在的虚假报告.

5> Marc Gravell..:

在.NET之间的差异Dictionary<,>,并HashTable主要是前者是一个泛型类型,所以你在静态类型检查(并降低拳击而言仿制药的所有好处,但这不是大如人们往往认为在性能条款 - 虽然拳击有一定的记忆成本.



6> rix0rrr..:

人们说词典与哈希表相同.

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

你也可以使用链表或搜索树来实现字典,它只是效率不高(对某些效率指标而言).


@ rix0rrr - 我认为你有倒退,一个字典使用HashTable而不是HashTable使用一个字典.
@JosephHamilton - rix0rrr说得对:"哈希表_是_dictionary_的一个实现." 他的意思是"字典",而不是类(注意小写).从概念上讲,哈希表实现了字典接口.在.NET中,Dictionary使用哈希表来实现IDictionary.这很麻烦;)
MS文档说:_"通过使用其键来检索值非常快,接近于O(1),因为Dictionary <(Of <(TKey,TValue>)>)类被实现为哈希表."_ - 因此在处理`Dictionary `时应该保证哈希表.`IDictionary `可能是任何东西,但:)
@JosephHamilton:*implements*(或**的实现)甚至远不及*使用*.恰恰相反.如果他说的略有不同(但意思相同),也许会更清楚:"哈希表是实现字典的一种方式".也就是说,如果你想要字典的功能,那么一种方法(实现*字典)就是使用哈希表.

7> Sujit..:

Collections&Generics对于处理对象组很有用.在.NET中,所有集合对象都在接口之下,接口IEnumerable又具有ArrayList(Index-Value))&HashTable(Key-Value).在.NET framework 2.0之后,ArrayList&HashTable被替换为List&Dictionary.现在,在现在的项目中不再使用Arraylist&HashTable.

来到之间的区别HashTableDictionary,Dictionary是通用的,其中如Hastable不通用.我们可以添加任何类型的对象HashTable,但在检索时我们需要将其强制转换为所需的类型.所以,它不是类型安全的.但是dictionary,在声明自己时我们可以指定键和值的类型,因此在检索时不需要进行转换.

我们来看一个例子:

哈希表

class HashTableProgram
{
    static void Main(string[] args)
    {
        Hashtable ht = new Hashtable();
        ht.Add(1, "One");
        ht.Add(2, "Two");
        ht.Add(3, "Three");
        foreach (DictionaryEntry de in ht)
        {
            int Key = (int)de.Key; //Casting
            string value = de.Value.ToString(); //Casting
            Console.WriteLine(Key + " " + value);
        }

    }
}

字典,

class DictionaryProgram
{
    static void Main(string[] args)
    {
        Dictionary dt = new Dictionary();
        dt.Add(1, "One");
        dt.Add(2, "Two");
        dt.Add(3, "Three");
        foreach (KeyValuePair kv in dt)
        {
            Console.WriteLine(kv.Key + " " + kv.Value);
        }
    }
}


而不是显式地为KeyValuePair分配数据类型,我们可以使用var.所以,这会减少输入 - foreach(在dt中的var kv)......只是一个建议.

8> Altaf Patel..:

字典:

如果我们试图找到一个不存在的密钥,它会返回/抛出异常.

它比Hashtable更快,因为没有装箱和拆箱.

只有公共静态成员是线程安全的.

Dictionary是一种泛型类型,这意味着我们可以将它与任何数据类型一起使用(创建时,必须指定键和值的数据类型).

例: Dictionary = new Dictionary();

Dictionay是Hashtable的类型安全实现,Keys并且Values是强类型的.

哈希表:

如果我们试图找到一个不存在的密钥,它将返回null.

它比字典慢,因为它需要装箱和拆箱.

Hashtable中的所有成员都是线程安全的,

Hashtable不是通用类型,

Hashtable是松散类型的数据结构,我们可以添加任何类型的键和值.



9> alexandrekow..:

使用 MSDN上的C#文章对数据结构的广泛检查表明,冲突解决策略也存在差异 :

Hashtable类使用称为rehashing的技术.

Rehashing的工作原理如下:有一组散列不同的函数,H 1 ... H n,当从散列表中插入或检索项时,最初使用H 1散列函数.如果这导致碰撞,则尝试使用H 2,并且如果需要,则转发到H n.

字典使用称为链接的技术.

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



10> Oliver..:

从.NET Framework 3.5开始HashSet,Dictionary如果只需要密钥而没有值,那么它还提供了所有优点.

因此,如果您使用a Dictionary并始终将值设置null为模拟类型安全哈希表,您应该考虑切换到HashSet.



11> flesh..:

Hashtable是一个松散类型的数据结构,因此您可以将任何类型的键和值添加到Hashtable.该Dictionary班是一种安全的Hashtable实现和键和值是强类型.创建Dictionary实例时,必须为键和值指定数据类型.



12> 小智..:

请注意,MSDN说:"Dictionary <(Of <(TKey,TValue>)>)类实现为哈希表 ",而不是"Dictionary <(Of <(TKey,TValue>)>)类实现为HashTable "

Dictionary不是作为HashTable实现的,而是按照哈希表的概念实现的.由于使用了Generics,实现与HashTable类无关,尽管内部Microsoft可能使用了相同的代码并用TKey和TValue替换了Object类型的符号.

在.NET 1.0中,Generics不存在; 这是HashTable和ArrayList最初开始的地方.



13> Siva Sankar ..:

哈希表:

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

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

这些操作非常昂贵.我们需要尽可能避免装箱/拆箱.

字典: HashTable的通用变体.

没有拳击/拆箱.无需转换.



14> mparkuk..:

Hashtable对象由包含集合元素的存储桶组成.存储桶是Hashtable中虚拟的元素子组,与大多数集合相比,它使搜索和检索更容易,更快捷.

Dictionary类与Hashtable类具有相同的功能.特定类型的字典(除了Object)具有比值类型的Hashtable更好的性能,因为Hashtable的元素是Object类型,因此,如果存储或检索值类型,通常会发生装箱和取消装箱.

进一步阅读:Hashtable和字典集合类型



15> NullReferenc..:

另一个重要的区别是Hashtable是线程安全的.Hashtable内置多个读取器/单个写入器(MR/SW)线程安全性,这意味着Hashtable允许一个编写器与多个读取器一起使用而无需锁定.

在Dictionary的情况下,没有线程安全; 如果您需要线程安全,则必须实现自己的同步.

进一步阐述:

Hashtable通过Synchronized属性提供一些线程安全性,它返回集合周围的线程安全包装器.包装器通过在每次添加或删除操作时锁定整个集合来工作.因此,尝试访问集合的每个线程必须等待轮到一个锁.这不可扩展,可能会导致大型集合的性能显着下降.此外,该设计并未完全免受竞争条件的影响.

.NET Framework 2.0集合类List, Dictionary等不提供任何线程同步; 用户代码必须在多个线程上同时添加或删除项目时提供所有同步

如果您需要类型安全性以及线程安全性,请在.NET Framework中使用并发集合类.进一步阅读这里.

另一个区别是,当我们在Dictionary中添加多个条目时,将保留添加条目的顺序.当我们从Dictionary中检索项目时,我们将按照插入它们的相同顺序获取记录.而Hashtable不保留插入顺序.


“某些线程安全性”与“线程安全性”不同

16> 小智..:

我能想到的另一个不同之处是:

我们不能将Dictionary (泛型)与Web服务一起使用.原因是没有Web服务标准支持泛型标准.



17> Kishore Kuma..:

Dictionary<> 是一种通用类型,所以它的类型安全.

您可以在HashTable中插入任何值类型,这有时会引发异常.但是Dictionary只接受整数值,同样Dictionary只接受字符串.

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

推荐阅读
k78283381
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有