Dictionary和Hashtable之间的区别

bli*_*egz 106 c# collections

可能重复:
为什么Dictionary优先于C#中的哈希表?

Dictionary和Hashtable有什么区别.如何决定使用哪一个?

Mar*_*ell 192

简单来说,Dictionary<TKey,TValue>是一种通用类型,允许:

  • 静态类型(和编译时验证)
  • 没有拳击使用

如果您是.NET 2.0或更高版本,您应该更喜欢 Dictionary<TKey,TValue>(和其他通用集合)

一个微妙但重要的区别是Hashtable支持多个读取器线程与单个编写器线程,而不Dictionary提供线程安全性.如果您需要使用通用字典的线程安全性,则必须实现自己的同步或(在.NET 4.0中)使用ConcurrentDictionary<TKey, TValue>.

  • 但是,与Hashtable不同,Dictionary的实例方法不是线程安全的 (3认同)

Pri*_*ndy 82

让我们举一个例子来解释哈希表和字典之间的区别.

这是一个实现哈希表的方法

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;
    //}
}
Run Code Online (Sandbox Code Playgroud)

以下是字典

  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;
    }
  }
Run Code Online (Sandbox Code Playgroud)

  • 优秀!!!!!!!!!!!!! (6认同)
  • 很好的答案.通过实例解释总是比写作理论更好. (3认同)
  • 作为注释.....您可以枚举Hashtable属性,如下所述:http://msdn.microsoft.com/en-us/library/system.collections.hashtable.aspx.您必须使用DictionaryEntry作为变量,然后可以提供键和值对象. (2认同)

Roh*_*pta 22

HashTable和Dictionary之间还有一个更重要的区别.如果您使用索引器从HashTable中获取值,则HashTable将成功为不存在的项返回null,而如果您尝试使用Dictionary中不存在的索引器访问项,则Dictionary将抛出错误


Fra*_*uma 12

字典是键入的(所以valuetypes不需要装箱),Hashtable不是(所以valuetypes需要装箱).Hashtable有一种比字典IMHO更好的获取值的方法,因为它总是知道值是一个对象.虽然如果你使用.NET 3.5,很容易为字典编写扩展方法以获得类似的行为.

如果每个键需要多个值,请在此处查看我的MultiValueDictionary源代码: .NET中的multimap

  • 对于每个键的多个值:在.NET 3.5中,您可能还会考虑实现`ILookup <TKey,TValue>`(这是多映射接口).不幸的是,默认的具体实现是不可变的,但很容易重新实现(或添加到MultiValueDictionary).在MiscUtil中有一个简单的例子(EditableLookup <TKey,TValue>) (2认同)

Pra*_*ngh 10

想要添加差异:

尝试访问不存在的密钥会在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
Run Code Online (Sandbox Code Playgroud)

键0和键"10"没有错误(注意: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]);
Run Code Online (Sandbox Code Playgroud)

这里错误为键0和键10,因为两者都不存在于字典,运行时错误,同时尝试访问.


Ras*_*dit 6

Hashtable类是一种特定类型的字典类,它使用整数值(称为哈希)来帮助存储其键.Hashtable类使用哈希来加速搜索集合中的特定键..NET中的每个对象都派生自Object类.此类支持GetHash方法,该方法返回唯一标识对象的整数.Hashtable类通常是非常有效的集合.Hashtable类的唯一问题是它需要一些开销,而对于小型集合(少于十个元素),开销会妨碍性能.

必须考虑两者之间的一些特殊区别:

HashTable:是非泛型集合,此集合的最大开销是它会自动为您的值进行装箱,并且为了获得您需要执行拆箱的原始值,这些会降低您的应用程序性能作为惩罚.

字典:这是一种通用类型的集合,其中没有隐式装箱,因此无需取消装箱,您将始终获得存储的原始值,这样可以提高应用程序性能.

第二个相当大的差异是:

如果你试图根据不存在的密钥从哈希表中访问一个值,它将返回null.但是在Dictionary的情况下它会给你KeyNotFoundException.

  • 真正具有讽刺意味的是,我正在阅读相同的MCTS书籍,对于喜欢哪一本感到困惑,在这里发布并得到了我刚才以你的答案形式阅读的相同文字!:)感谢您回复nyways .. (4认同)
  • 不是很讽刺...... Hashtable和Dictionary <,>都基于这种方法,因此它不会以任何方式回答在它们之间进行选择的问题. (2认同)