Dictionary和Hashtable之间的区别
可能重复:
为什么Dictionary在C#中比hashtable更受欢迎?
Dictionary和Hashtable有什么区别? 如何决定使用哪一个?
简单地说, Dictionary<TKey,TValue>
是一个通用types,允许:
- 静态types(和编译时validation)
- 没有拳击使用
如果你是.NET 2.0或以上,你应该更喜欢 Dictionary<TKey,TValue>
(和其他通用集合)
一个微妙的但重要的区别是Hashtable
支持多个读者线程与一个单一的写作者线程,而Dictionary
提供没有线程安全。 如果使用通用字典需要线程安全性,则必须实现自己的同步,或者(在.NET 4.0中)使用ConcurrentDictionary<TKey, TValue>
。
让我们举个例子来解释哈希表和字典之间的区别。
这是一个实现散列表的方法
public void MethodHashTable() { Hashtable objHashTable = new Hashtable(); objHashTable.Add(1, 100); // int objHashTable.Add(2.99, 200); // float objHashTable.Add('A', 300); // char objHashTable.Add("4", 400); // string lblDisplay1.Text = objHashTable[1].ToString(); lblDisplay2.Text = objHashTable[2.99].ToString(); lblDisplay3.Text = objHashTable['A'].ToString(); lblDisplay4.Text = objHashTable["4"].ToString(); // ----------- Not Possible for HashTable ---------- //foreach (KeyValuePair<string, int> pair in objHashTable) //{ // lblDisplay.Text = pair.Value + " " + lblDisplay.Text; //} }
以下是字典
public void MethodDictionary() { Dictionary<string, int> dictionary = new Dictionary<string, int>(); dictionary.Add("cat", 2); dictionary.Add("dog", 1); dictionary.Add("llama", 0); dictionary.Add("iguana", -1); //dictionary.Add(1, -2); // Compilation Error foreach (KeyValuePair<string, int> pair in dictionary) { lblDisplay.Text = pair.Value + " " + lblDisplay.Text; } }
HashTable和Dictionary之间还有一个更重要的区别。 如果使用索引器从HashTable中获取值,则HashTable将成功地为不存在的项目返回null,而如果尝试使用字典中不存在的索引器访问项目,Dictionary将引发错误
Dictionary是键入的(所以valueetypes不需要装箱),一个Hashtable不是(所以valueetypes需要装箱)。 哈希表有一个更好的方式来获得一个值比字典恕我直言,因为它总是知道这个值是一个对象。 虽然如果你使用的是.NET 3.5,那么写一个字典的扩展方法来获得类似的行为是很容易的。
如果您需要每个键的多个值,请查看我的MultiValueDictionary的源代码: 在.NET中的multimap
想添加一个区别:
尝试访问一个不存在的键在Dictionary中给出运行时错误,但在散列表中没有问题,因为它返回null而不是错误。
例如
//No strict type declaration Hashtable hash = new Hashtable(); hash.Add(1, "One"); hash.Add(2, "Two"); hash.Add(3, "Three"); hash.Add(4, "Four"); hash.Add(5, "Five"); hash.Add(6, "Six"); hash.Add(7, "Seven"); hash.Add(8, "Eight"); hash.Add(9, "Nine"); hash.Add("Ten", 10);// No error as no strict type for(int i=0;i<=hash.Count;i++)//=>No error for index 0 { //Can be accessed through indexers Console.WriteLine(hash[i]); } Console.WriteLine(hash["Ten"]);//=> No error in Has Table
这里没有错误的关键0还为关键“十”(注:吨很小)
//Strict type declaration Dictionary<int,string> dictionary= new Dictionary<int, string>(); dictionary.Add(1, "One"); dictionary.Add(2, "Two"); dictionary.Add(3, "Three"); dictionary.Add(4, "Four"); dictionary.Add(5, "Five"); dictionary.Add(6, "Six"); dictionary.Add(7, "Seven"); dictionary.Add(8, "Eight"); dictionary.Add(9, "Nine"); //dictionary.Add("Ten", 10);// error as only key, value pair of type int, string can be added //for i=0, key doesn't exist error for (int i = 1; i <= dictionary.Count; i++) { //Can be accessed through indexers Console.WriteLine(dictionary[i]); } //Error : The given key was not present in the dictionary. //Console.WriteLine(dictionary[10]);
这里错误的关键字0也是关键10,因为两者都不存在字典,运行时错误,而尝试访问。
Hashtable类是一种特定types的字典类,它使用整数值(称为散列)来帮助存储其密钥。 Hashtable类使用散列来加速search集合中的特定键。 .NET中的每个对象都是从Object类派生的。 这个类支持GetHash方法,它返回一个唯一标识对象的整数。 Hashtable类是一个非常有效的集合。 Hashtable类的唯一问题是它需要一些开销,而对于小集合(less于十个元素),开销可能会阻碍性能。
两者之间有一些特殊的区别,必须考虑:
HashTable:是非generics集合,这个集合最大的开销就是它为你的值自动进行装箱,为了得到你的原始值,你需要进行拆箱,这样可以降低你的应用性能。
词典:这是通用types的集合,没有隐式装箱,所以不需要拆箱,你将永远得到你存储的原始值,这样可以提高你的应用程序的性能。
第二个相当大的区别是:
如果你试图从不存在的键的基础上从哈希表访问一个值,它将返回null.But在Dictionary的情况下,它会给你KeyNotFoundException。
ILookup接口在.net 3.5中与linq一起使用。
HashTable是弱types的基类; DictionaryBase抽象类是强types的,并在内部使用一个HashTable。
我发现关于Dictionary的一个奇怪的事情,当我们在Dictionary中添加多个条目时,条目的添加顺序被保留。 因此,如果我在Dictionary上应用一个foreach,我将按照插入它们的顺序来获取logging。
而对于普通的HashTable,这是不正确的,因为当我在Hashtable中添加相同的logging时,顺序不被维护。 据我所知,Dictionary是基于Hashtable,如果这是真的,为什么我的Dictionary保持顺序,但HashTable不?
至于为什么他们的行为不同,这是因为generics字典实现了一个哈希表,但不是基于System.Collections.Hashtable。 generics字典实现基于从列表中分配键值对。 然后这些随机访问的哈希表桶被索引,但是当它返回一个枚举器时,它只是按照顺序走这个列表 – 只要条目不被重用,就是插入的顺序。
shiv govind Birlasoft。:)