111 votes

Différence entre dictionnaire et table de hachage

Duplicata possible :
Pourquoi le dictionnaire est préféré à la table de hachage en C# ?

Quelle est la différence entre Dictionary et Hashtable. Comment décider lequel utiliser ?

0 votes

Espérons que vous répondrez à cette question question vous fournit une bonne réponse

2 votes

Il semble que cette question doive être fermée en tant que doublon, et ses réponses fusionnées avec l'un des doublons.

0 votes

Bien que lié au langage Java, mais this Ce fil vaut la peine d'être lu pour connaître la différence entre HashMap y HashTable . Quelques différences s'appliquent également au monde C#.

199voto

Marc Gravell Points 482669

Tout simplement, Dictionary<TKey,TValue> est un type générique, permettant :

  • typage statique (et vérification à la compilation)
  • utilisation sans mise en boîte

Si vous êtes en .NET 2.0 ou plus, vous devez préférez Dictionary<TKey,TValue> (et les autres collections génériques)

Une différence subtile mais importante est que Hashtable supporte plusieurs threads de lecture avec un seul thread d'écriture, tandis que Dictionary n'offre pas de sécurité thread. Si vous avez besoin d'une sécurité thread avec un dictionnaire générique, vous devez mettre en œuvre votre propre synchronisation ou (dans .NET 4.0) utiliser la fonction ConcurrentDictionary<TKey, TValue> .

3 votes

Mais les méthodes d'instance du dictionnaire ne sont pas thread-safe, contrairement à la table de hachage.

86voto

Pritom Nandy Points 309

Prenons un exemple qui explique la différence entre une table de hachage et un dictionnaire.

Voici une méthode qui implémente le 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;
    //}
}

Le texte suivant est destiné au dictionnaire

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

3 votes

À titre d'information, vous pouvez énumérer les propriétés de Hashtable, comme décrit ici : msdn.microsoft.com/fr/us/library/ . Vous devez utiliser un DictionaryEntry comme variable, qui peut ensuite fournir des objets clé et valeur.

1 votes

Superbe réponse, vous pouvez également utiliser DictionaryEntry pour énumérer sur Hashtable.Ex : foreach(DictionaryEntry dnty in objHashTable ){lblDisplay.Text= dnty.Value + " " +dnty.Key}

0 votes

//Looping hastable foreach (DictionaryEntry entry in objHashTable ) { Console.WriteLine("{0}, {1}", entry.Key, entry.Value) ; }

24voto

Rohit Gupta Points 339

Il existe une autre différence importante entre une HashTable et un dictionnaire. Si vous utilisez des indexeurs pour extraire une valeur d'une HashTable, celle-ci renverra avec succès la valeur null pour un élément inexistant, alors que le Dictionary émettra une erreur si vous essayez d'accéder à un élément qui n'existe pas dans le Dictionary en utilisant un indexeur.

13voto

Frans Bouma Points 6015

Un dictionnaire est typé (donc les types de valeurs n'ont pas besoin d'être encadrés), une table de hachage ne l'est pas (donc les types de valeurs ont besoin d'être encadrés). Hashtable a une meilleure façon d'obtenir une valeur que dictionary IMHO, parce qu'il sait toujours que la valeur est un objet. Cependant, si vous utilisez .NET 3.5, il est facile d'écrire une méthode d'extension pour dictionary afin d'obtenir un comportement similaire.

Si vous avez besoin de plusieurs valeurs par clé, consultez mon code source de MultiValueDictionary ici : http://stackoverflow.com/questions/380595/multimap-in-c-3-0/380601#380601

2 votes

Pour les valeurs multiples par clé : dans .NET 3.5, vous pouvez également envisager de mettre en œuvre la fonction ILookup<TKey,TValue> (qui est l'interface multi-map). Malheureusement, l'implémentation concrète par défaut est immuable, mais il est facile de la réimplémenter (ou de l'ajouter à votre MultiValueDictionary). Il existe un exemple simple de ce type dans MiscUtil (EditableLookup<TKey,TValue>)

0 votes

Bon conseil en effet, j'avais oublié cette interface. J'ai regardé l'implémentation dans la BCL mais elle est en effet immuable, donc plutôt inutile pour une utilisation quotidienne de plusieurs valeurs ;). Je vais ajouter l'interface.

0 votes

10voto

Pranav Singh Points 3190

Vous voulez ajouter une différence :

Essayer d'accéder à une clé inexistante donne une erreur d'exécution dans le dictionnaire mais aucun problème dans la table de hachage qui renvoie null au lieu de l'erreur.

par exemple

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

ici pas d'erreur pour la touche 0 et aussi pour la touche "dix" (note : t est petit)

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

ici erreur pour la clé 0 & aussi pour la clé 10 car les deux sont inexistantes dans le dictionnaire, erreur d'exécution, tout en essayant d'accéder.

0 votes

Je suppose que vous devriez utiliser LINQ pour trouver le FirstOrDefault si vous essayez de travailler avec une collection en dehors de foreach et for.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X