Dictionary和Hashtable有什么区别。如何决定使用哪一个?
答案 0 :(得分:190)
简单地说,Dictionary<TKey,TValue>
是一种通用类型,允许:
如果您是.NET 2.0或更高版本,则更喜欢 Dictionary<TKey,TValue>
(和其他通用集合)
一个微妙但重要的区别是Hashtable
支持具有单个编写器线程的多个读取器线程,而Dictionary
不提供线程安全性。如果您需要使用通用字典的线程安全性,则必须实现自己的同步或(在.NET 4.0中)使用ConcurrentDictionary<TKey, TValue>
。
答案 1 :(得分:81)
让我们举一个例子来解释哈希表和字典之间的区别。
这是一个实现哈希表的方法
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;
}
}
答案 2 :(得分:21)
HashTable和Dictionary之间还有一个更重要的区别。如果您使用索引器从HashTable中获取值,则HashTable将成功为不存在的项返回null,而如果您尝试使用Dictionary中不存在的索引器访问项,则Dictionary将抛出错误< / p>
答案 3 :(得分:11)
字典是键入的(所以valuetypes不需要装箱),Hashtable不是(因此值类型需要装箱)。 Hashtable有一种比字典IMHO更好的获取值的方法,因为它总是知道值是一个对象。虽然如果你使用.NET 3.5,很容易为字典编写扩展方法以获得类似的行为。
如果每个键需要多个值,请在此处查看我的MultiValueDictionary源代码: multimap in .NET
答案 4 :(得分:10)
想要添加差异:
尝试访问不存在的密钥会在Dictionary中产生运行时错误,但哈希表没有问题,因为它返回null而不是错误。
e.g。
//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和0;关键字“十”(注意:t很小)
//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和0;对于密钥10也是如此,因为两者都不存在于字典,运行时错误,同时尝试访问。
答案 5 :(得分:6)
Hashtable类是一种特定类型的字典类,它使用整数值(称为哈希)来帮助存储其键。 Hashtable类使用哈希来加速搜索集合中的特定键。 .NET中的每个对象都派生自Object类。此类支持GetHash方法,该方法返回唯一标识对象的整数。 Hashtable类通常是非常有效的集合。 Hashtable类的唯一问题是它需要一些开销,而对于小型集合(少于十个元素),开销会妨碍性能。
两者之间存在一些必须考虑的特殊区别:
HashTable:是非泛型集合,这是最大的开销 集合是它为你的价值观自动装箱 为了获得原始值,您需要执行拆箱, 这些会降低您的应用程序性能。
Dictionary:这是一个通用的集合类型,没有隐式 拳击,所以不需要取消装箱,你将永远得到你的原始 您存储的值,以便改善您的应用程序 性能
第二个相当大的差异是:
如果你试图在哈希表的基础上访问一个值 不存在的密钥将返回null。但是在。的情况下 字典它会给你KeyNotFoundException。
答案 6 :(得分:3)
ILookup接口在.net 3.5中使用linq。
HashTable是弱类型的基类; DictionaryBase 抽象类是stronly类型,并在内部使用HashTable。
我发现关于Dictionary的一个奇怪的事情,当我们在Dictionary中添加多个条目时,维护了添加条目的顺序。因此,如果我在字典上应用foreach,我将按照插入它们的顺序获取记录。
然而,普通的HashTable不是这样,因为当我在Hashtable中添加相同的记录时,订单不会被维护。据我所知,Dictionary基于Hashtable,如果这是真的,为什么我的Dictionary维持顺序,但HashTable没有?
至于它们为什么表现不同,这是因为Generic Dictionary实现了哈希表,但不是基于System.Collections.Hashtable。通用字典实现基于从列表中分配键值对。然后使用散列表桶对这些进行索引以进行随机访问,但是当它返回枚举器时,它只是按顺序遍历列表 - 只要不重复使用条目,这将是插入的顺序。
shv govind Birlasoft:)