1568 Stimmen

Warum wird Dictionary gegenüber Hashtable in C# bevorzugt?

In den meisten Programmiersprachen werden Wörterbücher gegenüber Hashtabellen bevorzugt. Was sind die Gründe dafür?

32 Stimmen

> Dies ist nicht unbedingt richtig. Eine Hashtabelle ist eine Implementierung eines Wörterbuchs. Eine typische Implementierung, und sie mag die Standardimplementierung in .NET sein, aber sie ist nicht per Definition die einzige. Ich bin mir nicht sicher, ob dies vom ECMA-Standard gefordert wird, aber die MSDN-Dokumentation sehr deutlich, dass es als Hashtable implementiert ist. Sie bieten sogar die SortedList-Klasse für Zeiten, in denen eine Alternative sinnvoller ist.

25 Stimmen

@Promit Ich dachte immer, die Dictionary war eine Implementierung des Hashtable .

2 Stimmen

Ich denke, der Grund dafür ist, dass man in einem Dictionary den Typ des Schlüssels und des Wertes selbst definieren kann. Die Hashtable kann nur Objekte aufnehmen und speichert die Paare basierend auf dem Hash (von object.GetHashCode() ).

1719voto

Michael Madsen Punkte 52883

Was immer es wert ist, ein Wörterbuch es (konzeptionell) eine Hashtabelle.

Wenn Sie meinten: "Warum verwenden wir die Dictionary<TKey, TValue> Klasse anstelle der Hashtable Klasse?", dann ist das eine einfache Antwort: Dictionary<TKey, TValue> ist ein generischer Typ, Hashtable nicht ist. Das heißt, Sie erhalten Typensicherheit mit Dictionary<TKey, TValue> weil man nicht jedes beliebige Objekt einfügen kann und die Werte, die man herausnimmt, nicht umwandeln muss.

Interessant ist, dass die Dictionary<TKey, TValue> Implementierung im .NET Framework basiert auf dem Hashtable wie Sie aus diesem Kommentar im Quellcode ersehen können:

Das generische Wörterbuch wurde aus der Quelle von Hashtable kopiert

Quelle

448 Stimmen

Und auch generische Sammlungen sind viel schneller, da sie nicht verpackt und entpackt werden müssen.

7 Stimmen

Nicht sicher über eine Hashtable mit der obigen Aussage, aber für ArrayList vs List<t> es ist wahr

42 Stimmen

Hashtable verwendet Object, um Dinge intern zu halten (Nur nicht-generische Weise, es zu tun), so dass es auch zu box/unbox haben würde.

705voto

Marcel Toth Punkte 10266

Unterschiede

Dictionary

Hashtable

Allgemein

Nicht-Generika

Benötigt eigene Thread-Synchronisation

Angebote fadensicher Version durch Synchronized() Methode

Aufgezähltes Element: KeyValuePair

Aufgezähltes Element: DictionaryEntry

Neuere (> .NET 2.0 )

Älter (seit .NET 1.0 )

ist in System.Collections.Generic

ist in System.Sammlungen

Anfrage an nicht existierenden Schlüssel löst eine Ausnahme aus

Anfrage an nicht existierenden Schlüssel gibt null zurück

möglicherweise ein bisschen schneller für Werttypen

etwas langsamer (benötigt Boxing/Unboxing) für Werttypen

Ähnlichkeiten:

  • Beide sind intern Hashtabellen \== schneller Zugriff auf Daten mit vielen Einträgen nach einem Schlüssel
  • Beide brauchen unveränderliche und eindeutige Schlüssel
  • Schlüssel von beiden brauchen eigene GetHashCode() Methode

Alternative .NET-Sammlungen:

(Kandidaten für die Verwendung anstelle von Dictionary und Hashtable)

  • ConcurrentDictionary - fadensicher (kann sicher von mehreren Threads gleichzeitig aufgerufen werden)
  • HybridDictionary - optimierte Leistung (für wenige Artikel und auch für viele Artikel)
  • OrderedDictionary - Werte können sein Zugriff über int index (in der Reihenfolge, in der sie hinzugefügt wurden)
  • SortedDictionary - Artikel automatisch sortiert
  • StringDictionary - stark typisiert und optimiert für Strings (jetzt veraltet zu Gunsten von Dictionary<string,string>)

14 Stimmen

@Guillaume86, aus diesem Grund verwenden Sie TryGetValue. msdn.microsoft.com/de-us/library/bb347013.aspx

3 Stimmen

+1 für StringDictionary ...Übrigens StringDictionary ist nicht dasselbe wie Dictionary<string, string> wenn Sie den Standardkonstruktor verwenden.

0 Stimmen

Die ParallelExtensionsExtras @ code.msdn.microsoft.com/windowsdesktop/ enthält ein ObservableConcurrentDictionary, das sowohl für die Bindung als auch für die Gleichzeitigkeit geeignet ist.

195voto

gius Punkte 8855

Denn Dictionary ist eine generische Klasse ( Dictionary<TKey, TValue> ), so dass der Zugriff auf seinen Inhalt typsicher ist (d. h. Sie müssen nicht von Object wie Sie es mit einer Hashtable ).

Vergleichen Sie

var customers = new Dictionary<string, Customer>();
...
Customer customer = customers["Ali G"];

a

var customers = new Hashtable();
...
Customer customer = customers["Ali G"] as Customer;

しかし Dictionary ist intern als Hash-Tabelle implementiert, so dass es technisch gesehen auf die gleiche Weise funktioniert.

98voto

user38902 Punkte 951

Zu Ihrer Information: In .NET, Hashtable ist thread-sicher für die Verwendung durch mehrere Lese-Threads und einen einzelnen Schreib-Thread, während in Dictionary Öffentliche statische Mitglieder sind thread-sicher, aber alle Instanzmitglieder sind nicht garantiert thread-sicher.

Wir mussten alle unsere Wörterbücher wieder auf Hashtable deshalb.

13 Stimmen

Spaß. Der Dictionary<T>-Quellcode sieht viel sauberer und schneller aus. Es könnte besser sein, Dictionary zu verwenden und eine eigene Synchronisation zu implementieren. Wenn die Dictionary-Lesevorgänge unbedingt aktuell sein müssen, dann müssen Sie einfach den Zugriff auf die Lese-/Schreibmethoden des Dictionarys synchronisieren. Das würde eine Menge Sperren bedeuten, aber es wäre korrekt.

11 Stimmen

Wenn Ihre Lesevorgänge nicht absolut aktuell sein müssen, können Sie das Wörterbuch alternativ als unveränderlich behandeln. Sie könnten dann einen Verweis auf das Wörterbuch nehmen und Leistung gewinnen, indem Sie Lesevorgänge überhaupt nicht synchronisieren (da es unveränderlich und inhärent thread-sicher ist). Um es zu aktualisieren, erstellen Sie eine vollständige aktualisierte Kopie des Wörterbuchs im Hintergrund und tauschen dann einfach die Referenz mit Interlocked.CompareExchange aus (unter der Annahme eines einzigen schreibenden Threads; mehrere schreibende Threads würden eine Synchronisierung der Aktualisierungen erfordern).

49 Stimmen

Mit .Net 4.0 wurde die ConcurrentDictionary Klasse, in der alle öffentlichen/geschützten Methoden thread-sicher implementiert sind. Wenn Sie keine Legacy-Plattformen unterstützen müssen, können Sie auf diese Weise die Hashtable in Multithreading-Code: msdn.microsoft.com/de-us/library/dd287191.aspx

72voto

Marc Gravell Punkte 970173

In .NET ist der Unterschied zwischen Dictionary<,> y HashTable ist in erster Linie, dass der erste ein generischer Typ ist, so dass Sie alle Vorteile der Generika in Bezug auf die statische Typüberprüfung (und reduzierte Boxing, aber das ist nicht so groß, wie die Leute in Bezug auf die Leistung zu denken neigen - es gibt eine definitive Speicher Kosten zu Boxing, though) erhalten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X