2008-11-03 7 views
9

Ich habe ein Wörterbuch, auf das ich normalerweise mit einem Schlüssel zugreife, also brauche ich schnelle Lesezugriffe mit wahlfreiem Zugriff. Für eine Funktion muss ich jedoch jeden Eintrag im Wörterbuch bearbeiten, in dem die Reihenfolge wichtig ist. Es scheint in Tests in Ordnung zu sein. Ist es in Ordnung, sich auf die Reihenfolge der Elemente in einem Wörterbuch zu verlassen?Wenn ich durch ein Dictionary (.NET generische Datenstruktur) iteriere, wird es in der gleichen Reihenfolge sein, die ich ihnen hinzugefügt habe?

Antwort

10

Nein. Wenn Sie eine Bestellung aufbewahren müssen, sollten Sie auch eine Liste mit Artikeln haben. Sie könnten alle Operationen kapseln, die Sie in Ihrer eigenen Erfassungsklasse benötigen, wodurch sowohl das Wörterbuch als auch die Liste gleichzeitig aktualisiert werden.

Es ist bedauerlich, dass .NET kein Wörterbuch hat, das dies selbst unterstützt - es ist eine ziemlich häufige Anfrage - Java tut, als LinkedHashMap.

-1

Nein. Sie sind besser dran mit einem SortedDictionary, wenn Sie Ihre Schlüssel in einer Bestellung aufbewahren möchten.

Bearbeiten: Entweder das, oder fügen Sie Ihre Schlüssel zu einer verknüpften Liste, wenn Sie verfolgen möchten, die Reihenfolge, die Sie die Elemente hinzugefügt haben.

+0

Verwenden eines sortierten Wörterbuchs hat keine direkte Korrelation mit Iterationen durch Elemente in der Reihenfolge, in der sie hinzugefügt wurden (siehe Betreff) –

0

tpower, Dictionary und SortedDictionary sind sehr ähnlich, da sie beide eine Sammlung von Objekten enthalten, die durch einen Schlüssel zugänglich sind. Wo sie sich unterscheiden, ist in der Art, wie sie intern gebaut sind.

Dictionary ist schneller für die Einfügung, soweit ich weiß, während SortedDictionary auf einem binären Baum Suchalgorithmus aufgebaut ist und schneller für das Zurücklesen ist.

In beiden Fällen wird die interne Reihenfolge jedoch durch die Schlüsselreihenfolge beibehalten. Es gibt keine Garantie dafür, dass die Reihenfolge, in der Sie durch die gesamte Sammlung iterieren, der Reihenfolge entspricht, in der Sie Ihre Elemente eingefügt haben.

In diesem Fall müssen Sie möglicherweise eine Liste und ein Wörterbuch für Ihre unterschiedlichen Anforderungen speichern.

+0

Für Wörterbuch ist die Reihenfolge einfach nicht definiert (und kann sich ändern, wenn sich die Größe ändert); es hängt nicht von der Taste * order * ab - hängt aber eindeutig von den Schlüsselwerten, deren Hashes, der Anzahl der Buckets usw. ab. –

+0

Re Leistung; SortedDictionary ist * langsamer * zu lesen; O (log n) für SortedList <,> und SortedDictionary <,>, vs O (1) für Dictionary <,>. Von den beiden sortiert, nimmt die SortedList <,> weniger Speicher und ist schneller * vorsortierte * Daten einfügen (für unsortierte Daten, SortedDictionary <,> ist schneller Insertion). –

+0

(langsamer zu lesen basierend auf Zugriffen nach Schlüssel; Quelle: MSDN) –

-2

Die Dokumentation eindeutig fest, dass „Für die Zwecke der Aufzählung, jedes Element in dem Wörterbuch als KeyValuePair behandelt wird < (Of < (TKey, TValue>)>) Struktur einen Wert und seine Schlüssel darstellt. Die Reihenfolge, in der Die zurückgegebenen Artikel sind nicht definiert.. " aber ich bin nicht überzeugt.

In allen Tests, die ich durchgeführt habe, werden die Artikel immer durch Einfügen sortiert.

Ich fand das seltsam, weil ich auch nicht korrekt HashMap und LinkedHashMap (in Java) und die Reihenfolge, in der HashMap getestet ist wie aber erwartet, wie Jon Skeet sagte, ist die Reihenfolge, in LinkedHashMap.

Kann jemand einen Fail-Test mit Dictionary zeigen?

Hier ist der Code I-Test verwenden:

 IDictionary<string, int> dic = new Dictionary<string, int>(10); 

     Console.WriteLine("Adding ..."); 
     for (int i = 0; i < 1000000; i++) 
     { 
      Guid guid = Guid.NewGuid(); 
      dic.Add(guid.ToString(), i); 
     } 
     Console.WriteLine("Testing ..."); 

     bool first = true; 
     int lastItem = 0; 
     foreach (var item in dic.Values) 
     { 
      if (first) 
      { 
       first = false; 
      } 
      else 
      { 
       if (lastItem != item - 1) 
       { 
        Console.WriteLine("Test Failed !"); 
        break; 
       } 

      } 
      lastItem = item; 
     } 
     Console.WriteLine("Done."); 
+0

Hmmmm ... sehr interessant! Selbst wenn ich viele Löschungen erzwinge, bleibt es ziemlich stabil. Wenn die Dokumente jedoch "undefined" sagen, wäre es keine gute Idee, sie zu ignorieren ... selbst wenn es heute stabil ist, muss es nicht sein. –

+1

Sie können sich auf keinen Fall auf diesen Test verlassen, um zu beweisen, dass das Wörterbuch für immer sortiert bleibt. Es kann sein, dass andere Änderungen im Speicher oder sogar die Zeit zwischen Einfügungen/Löschungen die Reihenfolge beeinflussen können, und die einzige Möglichkeit, sicher zu wissen, ist herauszufinden, wie das Wörterbuch hinter den Kulissen funktioniert, was keine einfache Aufgabe ist. . – gillyb

4

Sie auf jeden Fall auf Wörterbuch nicht < verlassen können> Ergebnisse in der Reihenfolge der Rückkehr Sie sie hinzugefügt haben - ebenso wie die Dokumentation Staaten.

Im Test scheint Dictionary <> immer KeyValuePairs <> in der gleichen Reihenfolge aufzuzählen, die sie hinzugefügt wurden. Die Mono-Implementierung von Dictionary <> tut dies jedoch nicht.Mono folgt der Dokumentation bei der Umsetzung von Verhalten, und ich nehme an, sie haben diesen Teil der Dokumentation gesehen und dann auf eine Art und Weise implementiert, die die Ordnung nicht aufrechterhalten hat.

Eine andere Option ist OrderedDictionary, die wird Reihenfolge beibehalten.