【发布时间】:2010-10-26 23:22:33
【问题描述】:
【问题讨论】:
标签: c# collections
【问题讨论】:
标签: c# collections
简单地说,Dictionary<TKey,TValue> 是一个泛型类型,允许:
如果你是 .NET 2.0 或更高版本,你应该首选Dictionary<TKey,TValue>(以及其他通用集合)
一个微妙但重要的区别是Hashtable 支持单个写入线程的多个读取线程,而Dictionary 不提供线程安全。如果您需要通用字典的线程安全,您必须实现自己的同步或(在 .NET 4.0 中)使用 ConcurrentDictionary<TKey, TValue>。
【讨论】:
字典是有类型的(所以值类型不需要装箱),哈希表不是(所以值类型需要装箱)。 Hashtable 具有比字典恕我直言更好的获取值的方法,因为它始终知道该值是一个对象。虽然如果您使用的是 .NET 3.5,很容易为字典编写扩展方法以获得类似的行为。
如果每个键需要多个值,请在此处查看我的 MultiValueDictionary 源代码: multimap in .NET
【讨论】:
ILookup<TKey,TValue>(这是多映射接口)。不幸的是,默认的具体实现是不可变的,但很容易重新实现(或添加到您的 MultiValueDictionary)。在 MiscUtil (EditableLookupHashtable 类是一种特定类型的字典类,它使用整数值(称为散列)来帮助存储其键。 Hashtable 类使用哈希来加快在集合中搜索特定键的速度。 .NET 中的每个对象都派生自 Object 类。此类支持 GetHash 方法,该方法返回唯一标识对象的整数。 Hashtable 类通常是一个非常有效的集合。 Hashtable 类的唯一问题是它需要一点开销,而且对于小型集合(少于 10 个元素),开销会影响性能。
必须考虑两者之间的一些特殊区别:
HashTable:是非泛型集合,这个开销最大 集合是它会自动为您的价值观和 为了获得您的原始价值,您需要执行拆箱, 这些会降低您的应用程序性能作为惩罚。
字典:这是集合的通用类型,其中没有隐式 装箱,因此无需拆箱,您将始终得到您的原件 您存储的值,因此它将改善您的应用程序 性能。
第二个显着的区别是:
如果您试图从哈希表中访问一个值 不存在的键将返回null。但在 字典它会给你 KeyNotFoundException。
【讨论】:
HashTable 和 Dictionary 之间还有一个重要的区别。如果您使用索引器从 HashTable 中获取值,则 HashTable 将为不存在的项目成功返回 null,而如果您尝试使用 Dictionary
【讨论】:
ILookup 接口在 .net 3.5 中与 linq 一起使用。
HashTable 是弱类型的基类;词典库 抽象类是强类型的,并在内部使用 HashTable。
我发现Dictionary有一个奇怪的地方,当我们在Dictionary中添加多个条目时,条目的添加顺序保持不变。因此,如果我在 Dictionary 上应用 foreach,我将按照插入它们的顺序获取记录。
然而,对于普通的 HashTable,情况并非如此,因为当我在 Hashtable 中添加相同的记录时,不会保持顺序。据我所知,Dictionary 是基于 Hashtable 的,如果这是真的,为什么我的 Dictionary 保持顺序而 HashTable 没有?
至于为什么它们的行为不同,这是因为通用字典实现了一个哈希表,但不是基于 System.Collections.Hashtable。通用字典实现基于从列表中分配键值对。然后使用哈希表存储桶对它们进行索引以进行随机访问,但是当它返回一个枚举器时,它只是按顺序遍历列表 - 只要不重复使用条目,这就是插入的顺序。
shiv govind Birlasoft.:)
【讨论】:
让我们举一个例子来解释哈希表和字典之间的区别。
这是一个实现hashtable的方法
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;
}
}
【讨论】:
想加个区别:
尝试访问不存在的键会在字典中出现运行时错误,但在哈希表中没有问题,因为它返回 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 和键“十”没有错误(注意: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 和键 10 出现此处错误,因为字典中不存在两者,运行时错误,同时尝试访问。
【讨论】: