2009-05-18 22 views
95

Mögliche Duplizieren:
Why Dictionary is preferred over hashtable in C#?Unterschied zwischen Wörterbuch und Hashtable

Was ist der Unterschied zwischen Wörterbuch und Hashtable ist. Wie zu entscheiden, welche zu verwenden?

+2

Es scheint, dass diese Frage als ein Duplikat geschlossen werden sollte, und ihre Antworten mit einem der Duplikate zusammengeführt werden. –

+0

hoffentlich Antworten auf diese [Frage] (http://stackoverflow.com/questions/301371/why-dictionary-isprefered-over-hashtable-in-c) bietet Ihnen eine gute Antwort – TheVillageIdiot

+0

Obwohl im Zusammenhang mit Java-Sprache aber [ this] (https://stackoverflow.com/q/40471/465053) thread ist lesenswert, um den Unterschied zwischen 'HashMap' und' HashTable' zu ​​erkennen. Wenige Unterschiede gelten auch für C# world. – RBT

Antwort

185

einfach, Dictionary<TKey,TValue> ein generischer Typ ist, so dass:

  • statische Typisierung (und Compiler-Verifikation)
  • Verwendung ohne Boxen

Wenn Sie .NET 2.0 oder höher sind, Sie sollten bevorzugenDictionary<TKey,TValue> (und die anderen generischen Sammlungen)

Eine subtile, aber ich Wichtiger Unterschied ist, dass Hashtable mehrere Leser-Threads mit einem einzigen Writer-Thread unterstützt, während Dictionary keine Threadsicherheit bietet. Wenn Sie Thread-Sicherheit mit einem allgemeinen Wörterbuch benötigen, müssen Sie eine eigene Synchronisierung implementieren oder (in .NET 4.0) ConcurrentDictionary<TKey, TValue> verwenden.

+3

Aber die Instanzmethoden des Dictionary sind nicht threadsicher, im Gegensatz zur Hashtable – t3mujin

11

Dictionary ist getippt (so müssen Werttypen nicht Boxen), eine Hashtable ist nicht (so müssen Werttypen boxen). Hashtable hat eine bessere Möglichkeit, einen Wert als Wörterbuch IMHO zu erhalten, weil es immer weiß, dass der Wert ein Objekt ist. Wenn Sie jedoch .NET 3.5 verwenden, ist es einfach, eine Erweiterungsmethode für das Wörterbuch zu schreiben, um ein ähnliches Verhalten zu erhalten.

Wenn Sie mehrere Werte pro Schlüssel benötigen, überprüfen hier meine Source MultiValueDictionary aus: multimap in .NET

+2

Für mehrere Werte pro Schlüssel: in .NET 3.5 könnten Sie auch die Implementierung von 'ILookup ' (die Multi-Map-Schnittstelle) in Betracht ziehen. Leider ist die standardmäßige konkrete Implementierung unveränderlich, aber es ist einfach, sie erneut zu implementieren (oder zu Ihrem MultiValueDictionary hinzuzufügen). Es gibt ein einfaches Beispiel für solche in MiscUtil (EditableLookup ) –

+0

Guter Tipp in der Tat, hatte ich über diese Schnittstelle vergessen. Ich habe mir die Implementierung in der BCL angeschaut, aber sie ist in der Tat unveränderlich, so ziemlich nutzlos für die alltägliche Verwendung mit mehreren Werten;). Ich werde die Schnittstelle hinzufügen. –

+0

Fertig. Wiederveröffentlichter Code: http://weblogs.asp.net/fbouma/archive/2009/05/18/multi-value-dictionary-c-source-code-net-3-5.aspx –

6

Die Hashtable-Klasse ist eine bestimmte Art von Wörterbuch-Klasse, die einen Integer-Wert verwendet (ein Hash genannt) in die unterstützen Speicherung seiner Schlüssel. Die Hashtable-Klasse verwendet den Hash, um die Suche nach einem bestimmten Schlüssel in der Sammlung zu beschleunigen. Jedes Objekt in .NET stammt von der Object-Klasse. Diese Klasse unterstützt die GetHash-Methode, die eine Ganzzahl zurückgibt, die das Objekt eindeutig identifiziert. Die Hashtable-Klasse ist im Allgemeinen eine sehr effiziente Sammlung. Das einzige Problem mit der Hashtable-Klasse ist, dass es ein wenig Aufwand erfordert, und bei kleinen Sammlungen (weniger als zehn Elemente) kann der Overhead die Leistung beeinträchtigen.

Es gibt einige besondere Unterschied zwischen beiden ist, die berücksichtigt werden müssen:

HashTable: ist nicht generische Sammlung, der größte Kopf dieser Sammlung ist, dass es Boxen tut automatisch für Ihre Werte und um Um Ihren ursprünglichen Wert zu erhalten, müssen Sie Unboxing durchführen, diese, um Ihre Anwendungsleistung als Strafe zu verringern.

Wörterbuch: Das ist allgemeine Art der Sammlung, wo keine impliziten Boxen, so dass keine Notwendigkeit, Sie Unboxing werden immer Ihre ursprünglichen Werte erhalten, die Sie gespeichert wurden, so wird es Ihre Anwendung Leistung zu verbessern.

der Zweite erheblicher Unterschied:

, wenn Ihr auf von Hash-Tabelle auf der Basis der Schlüssel einen Wert zuzugreifen versuchten, die es nicht geben wird null.But Rückkehr im Falle von Wörterbuch wird es geben Sie KeyNotFoundException.

+0

Meine Kommentare sind aus MCTS 2.0 Buch und seine bekommen -ve rep ... wie ironisch !!!! : D –

+2

Nicht wirklich sehr ironisch ... sowohl Hashtable als auch Dictionary <,> basieren auf diesem Ansatz, so dass es in keiner Weise die Frage der Wahl zwischen ihnen beantwortet. –

+4

Die wirkliche Ironie ist, dass ich das gleiche MCTS-Buch gelesen habe, wirklich verwirrt war, welches zu bevorzugen, postete es hier und bekam den gleichen Text, den ich gerade in Form Ihrer Antwort gelesen habe !!! :) Danke für die Antwort nyways .. – blitzkriegz

19

Es gibt einen weiteren wichtigen Unterschied zwischen HashTable und Dictionary. Wenn Sie mithilfe von Indexern einen Wert aus einer HashTable abrufen, gibt die HashTable erfolgreich Null für ein nicht vorhandenes Element zurück, wohingegen das Dictionary einen Fehler auslöst, wenn Sie versuchen, mit einem Indexer, der im Dictionary

nicht existiert, auf ein Element zuzugreifen
3

ILookup Interface wird in .net 3.5 mit linq verwendet.

Die HashTable ist die Basisklasse, die schwach ist; Die DictionaryBase abstrakte Klasse ist streng typisiert und verwendet intern eine HashTable.

Ich fand eine seltsame Sache über das Wörterbuch, wenn wir die mehreren Einträge in Dictionary hinzufügen, wird die Reihenfolge, in der die Einträge hinzugefügt werden, beibehalten. Wenn ich also eine foreach auf das Dictionary anwende, erhalte ich die Datensätze in der gleichen Reihenfolge, in der ich sie eingefügt habe.

Während dies mit normalen HashTable nicht wahr ist, wie wenn ich gleiche Datensätze in Hashtable hinzufügen, wird die Reihenfolge nicht beibehalten. Soweit ich weiß, basiert das Wörterbuch auf Hashtable, wenn das stimmt, warum mein Wörterbuch die Reihenfolge beibehält, aber HashTable nicht?

Warum sie sich anders verhalten, liegt daran, dass Generic Dictionary eine Hashtabelle implementiert, aber nicht auf System.Collections.Hashtable basiert. Die Implementierung des generischen Dictionary basiert auf der Zuordnung von Schlüssel/Wert-Paaren aus einer Liste. Diese werden dann mit den Hashtabellen-Buckets für den wahlfreien Zugriff indiziert. Wenn sie jedoch einen Enumerator zurückgibt, wird die Liste nur in der Reihenfolge durchlaufen, in der sie eingefügt werden, solange die Einträge nicht wiederverwendet werden.

shiv govind Birlasoft. :)

75

wir ein Beispiel geben, die den Unterschied zwischen hashtable und Wörterbuch erklären würde.

Hier ist eine Methode, die

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

Das folgende ist für Wörterbuch

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

Ausgezeichnet !!!!!!!!!!!!! – nawfal

+0

Super und einfach –

+3

Schöne Antwort. Es ist immer besser, durch Beispiele zu erklären, als Theorie zu schreiben. – Kenta

10

Möchten Sie einen Unterschied hinzufügen hashtable implementiert:

Der Versuch, Acess ein inexistent Schlüssel gibt Laufzeit Fehler in Dictionary aber kein Problem in der Hashtabelle, da es Null statt Fehler zurückgibt.

z.B.

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

hier kein Fehler für Schlüssel 0 & auch für Schlüssel „Zehn“ (Anmerkung: t ist klein)

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

hier Fehler für Schlüssel 0 & auch für Schlüssel 10 als beide im Wörterbuch inexistent sind , Laufzeitfehler, während versuchen zu greifen.

+0

Ich nehme an, Sie sollten 'LINQ' zu verwenden Suchen Sie das Element 'FirstOrDefault', wenn Sie versuchen, mit einer Sammlung außerhalb von foreach und for zu arbeiten. – ppumkin

Verwandte Themen