In den meisten Programmiersprachen werden Wörterbücher Hashtabellen vorgezogen. Was sind die Gründe dafür?
c#
.net
vb.net
data-structures
Nakul Chaudhary
quelle
quelle
Dictionary
eine Implementierung desHashtable
.HashTable
. Wenn sie der Sprache Generika hinzufügten, nannten sie die generische VersionDictionary
. Beide sind Hash-Tabellen.Antworten:
Für was es wert ist , ein Wörterbuch ist (konzeptuell) eine Hash - Tabelle.
Wenn Sie meinten "Warum verwenden wir die
Dictionary<TKey, TValue>
Klasse anstelle derHashtable
Klasse?", Dann ist es eine einfache Antwort: IstDictionary<TKey, TValue>
ein generischer Typ,Hashtable
nicht. Das bedeutet, dass Sie Typensicherheit erhaltenDictionary<TKey, TValue>
, da Sie kein zufälliges Objekt einfügen können und die herausgenommenen Werte nicht umwandeln müssen.Interessanterweise
Dictionary<TKey, TValue>
basiert die Implementierung in .NET Framework auf demHashtable
, wie Sie diesem Kommentar im Quellcode entnehmen können:Quelle
quelle
HashTable
(Klasse) als auchDictionary
(Klasse) sind Hash-Tabellen (Konzept), aber aHashTable
ist weder aDictionary
nochDictionary
aHashTable
. Sie werden auf sehr ähnlicheDictionary<Object,Object>
Weise verwendet und können auf dieselbe untypisierte Weise wie a agierenHashTable
, teilen jedoch keinen Code direkt (obwohl Teile wahrscheinlich auf sehr ähnliche Weise implementiert werden).Dictionary
<<< >>>Hashtable
Unterschiede:Synchronized()
MethodeKeyValuePair
<<< >>> Aufzählungselement:DictionaryEntry
Dictionary
/Hashtable
Ähnlichkeiten:GetHashCode()
MethodeÄhnliche .NET-Sammlungen (Kandidaten, die anstelle von Dictionary und Hashtable verwendet werden sollen):
ConcurrentDictionary
- Thread-sicher (kann von mehreren Threads gleichzeitig sicher aufgerufen werden)HybridDictionary
- optimierte Leistung (für wenige Artikel und auch für viele Artikel)OrderedDictionary
- Auf Werte kann über den int-Index zugegriffen werden (in der Reihenfolge, in der die Elemente hinzugefügt wurden).SortedDictionary
- Artikel automatisch sortiertStringDictionary
- stark typisiert und für Strings optimiertquelle
StringDictionary
... ist übrigensStringDictionary
nicht dasselbe wieDictionary<string, string>
bei Verwendung des Standardkonstruktors.Da
Dictionary
eine generische Klasse (istDictionary<TKey, TValue>
), so dass sein Inhalt ist der Zugriff auf typsicher (dh Sie nicht gegossen aus benötigenObject
, wie Sie mit einem zu tunHashtable
).Vergleichen Sie
zu
Jedoch
Dictionary
wird als Hash - Tabelle intern implementiert, so technisch funktioniert es genauso.quelle
Zu Ihrer Information: In .NET
Hashtable
ist es threadsicher für die Verwendung durch mehrere Reader-Threads und einen einzelnen Schreibthread, während inDictionary
öffentlichen statischen Mitgliedern threadsicher sind, aber nicht garantiert wird, dass Instanzmitglieder threadsicher sind.Aus
Hashtable
diesem Grund mussten wir alle unsere Wörterbücher wieder ändern .quelle
ConcurrentDictionary
Klasse alle öffentlichen / geschützten Methoden threadsicher implementiert sind. Wenn Sie keine älteren Plattformen unterstützen müssen, können Sie denHashtable
Multithread-Code ersetzen : msdn.microsoft.com/en-us/library/dd287191.aspxIn .NET besteht der Unterschied zwischen
Dictionary<,>
undHashTable
in erster Linie darin, dass es sich bei dem ersteren um einen generischen Typ handelt. Sie erhalten also alle Vorteile von Generika in Bezug auf die statische Typprüfung (und das reduzierte Boxen), aber dies ist nicht so groß, wie die Leute denken Leistungsbedingungen - das Boxen verursacht jedoch bestimmte Speicherkosten.quelle
Die Leute sagen, dass ein Wörterbuch dasselbe ist wie eine Hash-Tabelle.
Dies ist nicht unbedingt wahr. Eine Hash-Tabelle ist eine Möglichkeit, ein Wörterbuch zu implementieren . Ein typischer, und es kann der Standard in .NET in der sein
Dictionary
Klasse, aber es ist per Definition nicht das einzige.Sie könnten ein Wörterbuch genauso gut mithilfe einer verknüpften Liste oder eines Suchbaums implementieren, es wäre einfach nicht so effizient (für eine Metrik der Effizienz).
quelle
Dictionary<K,V>
.IDictionary<K,V>
könnte aber alles sein :)Collections
&Generics
sind nützlich für die Behandlung von Objektgruppen. In .NET befinden sich alle Sammlungsobjekte unter der SchnittstelleIEnumerable
, die wiederum überArrayList(Index-Value))
& verfügtHashTable(Key-Value)
. Nach .NET Framework 2.0 wurdenArrayList
&HashTable
durchList
& ersetztDictionary
. Jetzt werden dieArraylist
&HashTable
in heutigen Projekten nicht mehr verwendet.Der Unterschied zwischen
HashTable
&Dictionary
,Dictionary
ist generisch, woHastable
nicht generisch ist. Wir können jedem Objekttyp hinzufügenHashTable
, aber beim Abrufen müssen wir ihn in den gewünschten Typ umwandeln. Es ist also nicht typsicher. Aberdictionary
, während sich erklären wir die Art von Schlüssel und Wert angeben können, so gibt es keine Notwendigkeit, Guss beim Abrufen.Schauen wir uns ein Beispiel an:
Hash-tabelle
Wörterbuch,
quelle
Wörterbuch:
Es gibt eine Ausnahme zurück / löst eine Ausnahme aus, wenn wir versuchen, einen Schlüssel zu finden, der nicht existiert.
Es ist schneller als ein Hashtable, da es kein Boxen und Unboxing gibt.
Nur öffentliche statische Mitglieder sind threadsicher.
Dictionary ist ein generischer Typ, dh wir können ihn mit jedem Datentyp verwenden (beim Erstellen müssen die Datentypen sowohl für Schlüssel als auch für Werte angegeben werden).
Beispiel:
Dictionary<string, string> <NameOfDictionaryVar> = new Dictionary<string, string>();
Dictionay ist eine typsichere Implementierung von Hashtable
Keys
undValues
stark typisiert.Hash-tabelle:
Es gibt null zurück, wenn wir versuchen, einen Schlüssel zu finden, der nicht existiert.
Es ist langsamer als das Wörterbuch, da es das Ein- und Auspacken erfordert.
Alle Mitglieder in einer Hashtabelle sind threadsicher.
Hashtable ist kein generischer Typ.
Hashtable ist eine lose typisierte Datenstruktur. Wir können Schlüssel und Werte jedes Typs hinzufügen.
quelle
Dictionary.TryGetValue
Die ausführliche Untersuchung von Datenstrukturen mithilfe des C # -Artikels zu MSDN besagt, dass es auch einen Unterschied in der Strategie zur Kollisionsauflösung gibt :
Die Hashtable-Klasse verwendet eine Technik, die als Aufwärmen bezeichnet wird .
Das Wörterbuch verwendet eine Technik, die als Verkettung bezeichnet wird .
quelle
Seit .NET Framework 3.5 gibt es auch eine,
HashSet<T>
die alle Vorteile bietet,Dictionary<TKey, TValue>
wenn Sie nur die Schlüssel und keine Werte benötigen.Wenn Sie also a verwenden
Dictionary<MyType, object>
und den Wert immer so einstellen, dass dienull
typsichere Hash-Tabelle simuliert wird, sollten Sie möglicherweise in Betracht ziehen, auf die zu wechselnHashSet<T>
.quelle
Dies
Hashtable
ist eine lose typisierte Datenstruktur, sodass Sie dem Schlüssel Schlüssel und Werte eines beliebigen Typs hinzufügen könnenHashtable
. DieDictionary
Klasse ist eine typsichereHashtable
Implementierung, und die Schlüssel und Werte sind stark typisiert. Beim Erstellen einerDictionary
Instanz müssen Sie die Datentypen sowohl für den Schlüssel als auch für den Wert angeben.quelle
Beachten Sie, dass MSDN sagt: "Dictionary <(Of <(TKey, TValue>)>) Klasse ist als Hash-Tabelle implementiert ", nicht "Dictionary <(Of <(TKey, TValue>)>) Klasse ist als HashTable implementiert ".
Dictionary wird NICHT als HashTable implementiert, sondern nach dem Konzept einer Hash-Tabelle. Die Implementierung hat aufgrund der Verwendung von Generics keine Beziehung zur HashTable-Klasse, obwohl Microsoft intern denselben Code hätte verwenden und die Symbole vom Typ Object durch TKey und TValue ersetzen können.
In .NET 1.0 gab es keine Generika. Hier begannen ursprünglich HashTable und ArrayList.
quelle
Hash-tabelle:
Schlüssel / Wert werden beim Speichern im Heap in einen Objekttyp (Boxing) konvertiert.
Schlüssel / Wert muss beim Lesen vom Heap in den gewünschten Typ konvertiert werden.
Diese Operationen sind sehr kostspielig. Wir müssen das Boxen / Unboxen so weit wie möglich vermeiden.
Wörterbuch: Generische Variante von HashTable.
Kein Boxen / Unboxen. Keine Konvertierungen erforderlich.
quelle
Ein Hashtable-Objekt besteht aus Buckets, die die Elemente der Sammlung enthalten. Ein Bucket ist eine virtuelle Untergruppe von Elementen in der Hashtabelle, wodurch das Suchen und Abrufen einfacher und schneller ist als in den meisten Sammlungen .
Die Dictionary-Klasse hat dieselbe Funktionalität wie die Hashtable-Klasse. Ein Wörterbuch eines bestimmten Typs (außer Objekt) bietet eine bessere Leistung als eine Hashtabelle für auf, da die Elemente der Hashtabelle vom Typ Objekt sind und daher beim Speichern oder Abrufen eines Werttyps normalerweise Boxing und Unboxing auftreten.
Weitere Informationen : Hashtable- und Dictionary-Auflistungstypen
quelle
Ein weiterer wichtiger Unterschied ist, dass Hashtable threadsicher ist. Hashtable verfügt über eine integrierte Thread-Sicherheit für mehrere Leser / einzelne Schreiber (MR / SW), was bedeutet, dass Hashtable EINEN Schreiber zusammen mit mehreren Lesern ohne Sperren ermöglicht.
Im Fall von Dictionary gibt es keine Thread-Sicherheit; Wenn Sie Thread-Sicherheit benötigen, müssen Sie Ihre eigene Synchronisation implementieren.
Um weiter auszuarbeiten:
Wenn Sie sowohl Typensicherheit als auch Thread-Sicherheit benötigen, verwenden Sie gleichzeitige Sammlungsklassen in .NET Framework. Lesen Sie hier weiter .
Ein zusätzlicher Unterschied besteht darin, dass beim Hinzufügen mehrerer Einträge im Wörterbuch die Reihenfolge beibehalten wird, in der die Einträge hinzugefügt werden. Wenn wir die Elemente aus dem Wörterbuch abrufen, erhalten wir die Datensätze in der Reihenfolge, in der wir sie eingefügt haben. Während Hashtable die Einfügereihenfolge nicht beibehält.
quelle
Hashset
garantiert dies die Sicherheit von MR / SW-Threads in Nutzungsszenarien, in denen keine Löschvorgänge erforderlich sind . Ich denke, es war möglicherweise beabsichtigt, vollständig MR / SW-sicher zu sein, aber die sichere Behandlung von Löschungen erhöht die Kosten für die MR / SW-Sicherheit erheblich. Während das Design vonDictionary
MR / SW-Sicherheit in Szenarien ohne Löschung zu minimalen Kosten hätte bieten können, wollte MS meiner Meinung nach vermeiden, Szenarien ohne Löschung als "speziell" zu behandeln.Ein weiterer Unterschied, den ich herausfinden kann, ist:
Wir können Dictionary <KT, VT> (Generika) nicht mit Webdiensten verwenden. Der Grund dafür ist, dass kein Webdienststandard den Generika-Standard unterstützt.
quelle
Dictionary<>
ist ein generischer Typ und daher typsicher.Sie können einen beliebigen Werttyp in HashTable einfügen, was manchmal eine Ausnahme auslöst.
Dictionary<int>
Akzeptiert aber nur ganzzahlige Werte und ähnlichDictionary<string>
wird nur Strings akzeptieren.Es ist also besser,
Dictionary<>
statt zu verwendenHashTable
.quelle
Ich denke nicht, dass dies unbedingt wahr ist, die meisten Sprachen haben die eine oder andere, abhängig von der Terminologie, die sie bevorzugen .
In C # ist der klare Grund (für mich) jedoch, dass C # HashTables und andere Mitglieder des System.Collections-Namespace weitgehend veraltet sind. Sie waren in c # V1.1 vorhanden. Sie wurden von C # 2.0 durch die generischen Klassen im System.Collections.Generic-Namespace ersetzt.
quelle
Nach dem, was ich mit .NET Reflector sehe :
So können wir sicher sein, dass DictionaryBase intern eine HashTable verwendet.
quelle