2009-05-18 25 views
95

Duplicar posibles:
Why Dictionary is preferred over hashtable in C#?Diferencia entre diccionario y Hashtable

¿Cuál es la diferencia entre diccionario y Hashtable. ¿Cómo decidir cuál usar?

+2

Parece que esta pregunta debe cerrarse como un duplicado, y sus respuestas se combinaron con uno de los duplicados. –

+0

esperemos que responda a esta [pregunta] (http://stackoverflow.com/questions/301371/why-dictionary-is-preferred-over-hashtable-in-c) le proporciona una buena respuesta – TheVillageIdiot

+0

Aunque está relacionado con el lenguaje de Java pero [ este] (https://stackoverflow.com/q/40471/465053) thread vale la pena leer para saber la diferencia entre 'HashMap' y' HashTable'. Pocas diferencias se aplican al mundo C# también. – RBT

Respuesta

185

Simplemente, Dictionary<TKey,TValue> es un tipo genérico, lo que permite:

  • tipos estáticos (y en tiempo de compilación verificación)
  • su uso sin el boxeo

Si está .NET 2.0 o superior, usted debe preferirDictionary<TKey,TValue> (y las otras colecciones genéricas)

Un sutil pero yo La diferencia más importante es que Hashtable admite múltiples hilos de lectura con una única secuencia de escritura, mientras que Dictionary no ofrece seguridad de subprocesos. Si necesita seguridad de subprocesos con un diccionario genérico, debe implementar su propia sincronización o (en .NET 4.0) usar ConcurrentDictionary<TKey, TValue>.

+3

Pero los métodos de instancia de Dictionary no son seguros para subprocesos, a diferencia del Hashtable – t3mujin

11

El diccionario está tipeado (por lo que los tipos de valores no necesitan boxeo), un Hashtable no (por lo tanto, los tipos de valores necesitan boxeo). Hashtable tiene una forma más agradable de obtener un valor que el diccionario en mi humilde opinión, porque siempre sabe que el valor es un objeto. Aunque si usa .NET 3.5, es fácil escribir un método de extensión para que el diccionario obtenga un comportamiento similar.

Si necesita múltiples valores por clave, echa un vistazo a mi código fuente de MultiValueDictionary aquí: multimap in .NET

+2

Para valores múltiples por clave: en .NET 3.5, también podría considerar implementar 'ILookup ' (que es la interfaz de múltiples mapas). Lamentablemente, la implementación concreta predeterminada es inmutable, pero es fácil de implementar (o agregar a su MultiValueDictionary). Hay un ejemplo simple de tal en MiscUtil (EditableLookup ) –

+0

Un buen consejo, me había olvidado de esa interfaz. Miré la implementación en el BCL, pero de hecho es inmutable, por lo que es prácticamente inútil para el uso de múltiples valores todos los días;). Agregaré la interfaz. –

+0

Hecho. Código republicado: http://weblogs.asp.net/fbouma/archive/2009/05/18/multi-value-dictionary-c-source-code-net-3-5.aspx –

6

La clase Hashtable es un tipo específico de clase diccionario que utiliza un valor entero (llamado un hash) para ayudar en la almacenamiento de sus llaves. La clase Hashtable usa el hash para acelerar la búsqueda de una clave específica en la colección. Cada objeto en .NET deriva de la clase Object. Esta clase admite el método GetHash, que devuelve un número entero que identifica de manera única el objeto. La clase Hashtable es una colección muy eficiente en general. El único problema con la clase Hashtable es que requiere un poco de sobrecarga, y para colecciones pequeñas (menos de diez elementos) la sobrecarga puede impedir el rendimiento.

hay alguna diferencia especial entre dos que deben ser considerados:

HashTable: es una colección no genérica, la mayor sobrecarga de esta colección es que el boxeo de forma automática para sus valores y con el fin para obtener su valor original, debe realizar unboxing, , para disminuir el rendimiento de la aplicación como penalización.

Diccionario: Este es el tipo genérico de colección donde hay implícita el boxeo, por lo que no hay necesidad de unboxing que siempre llegan a sus valores originales que se almacenaron por lo que mejorará su aplicación rendimiento.

La segunda diferencia es considerable:

si su estaban tratando de acceder a un valor desde tabla hash sobre la base de clave que no existe volverá null.But en el caso de que lo hará Diccionario darte KeyNotFoundException.

+0

Mis comentarios son del libro de MCTS 2.0 y su informe ... ¡qué irónico! : D –

+2

No es realmente muy irónico ... tanto Hashtable como Dictionary <,> se basan en este enfoque, por lo que no responde de ninguna manera la cuestión de elegir entre ellos. –

+4

La verdadera ironía es que estaba leyendo el mismo libro de MCTS, me confundí mucho sobre cuál preferiría, lo publiqué aquí y obtuve el mismo texto que acabo de leer en la forma de su respuesta. :) Gracias por responder de todas formas ... – blitzkriegz

19

Hay una diferencia más importante entre una HashTable y un Dictionary. Si utiliza indexadores para obtener un valor de una HashTable, la HashTable devolverá nulo con éxito para un elemento inexistente, mientras que el diccionario generará un error si intenta acceder a un elemento utilizando un indexador que no existe en el Diccionario

3

ILookup Interface se utiliza en .net 3.5 con linq.

La HashTable es la clase base que es de tipo débil; la clase abstracta DictionaryBase está fuertemente tipada y utiliza internamente una HashTable.

Encontré algo extraño sobre Dictionary, cuando agregamos las múltiples entradas en Dictionary, se mantiene el orden en que se agregan las entradas. Por lo tanto, si aplico un foreach en el Diccionario, obtendré los registros en el mismo orden en que los inserté.

Considerando que esto no es cierto con HashTable normal, ya que cuando agrego los mismos registros en Hashtable, el orden no se mantiene. Según mi conocimiento, Dictionary se basa en Hashtable, si esto es cierto, ¿por qué mi Dictionary mantiene el orden pero HashTable no?

En cuanto a por qué se comportan de manera diferente, es porque Generic Dictionary implementa una tabla hash, pero no se basa en System.Collections.Hashtable. La implementación del Diccionario genérico se basa en la asignación de pares clave-valor de una lista. Luego se indexan con los contenedores de hashtables para el acceso aleatorio, pero cuando devuelve un enumerador, simplemente recorre la lista en orden secuencial, que será el orden de inserción, siempre que las entradas no se reutilicen.

navaja govind Birlasoft. :)

75

permite darle un ejemplo que explicaría la diferencia entre la tabla hash y diccionario.

Aquí es un método que implementa tabla hash

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; 
    //} 
} 

La siguiente es para el diccionario

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; 
    } 
    } 
+5

¡¡¡Excelente !!!!!!!!!!!!! – nawfal

+0

Súper y simple –

+3

Buena respuesta. Siempre es mejor explicarlo a través de ejemplos que la teoría de la escritura. – Kenta

10

desea agregar una diferencia:

Tratando de acess una clave inexistente da tiempo de ejecución error en el diccionario, pero no hay problema en hashtable, ya que devuelve null en lugar de error.

p. Ej.

 //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 

aquí hay error de tecla 0 & también para tecla "diez" (nota: t es pequeña)

//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]); 

aquí el error de tecla 0 & también para llave 10 ya que ambos son inexistentes en el diccionario , error de tiempo de ejecución, mientras intentas acceder.

+0

Supongo que debe usar 'LINQ' para encuentre el ítem 'FirstOrDefault' si está tratando de trabajar con una colección fuera de foreach y para. – ppumkin

Cuestiones relacionadas