2016-04-10 8 views
1

This StackOverflow Antwort beschreibt vollständig, dass ein HashSet ungeordnet ist und seine Reihenfolge der Elementaufzählung ist nicht definiert und sollte nicht verlässlich sein.Hält HashSet die Reihenfolge zwischen Aufzählungen?

jedoch

Diese anouther Frage bringt: soll ich oder soll ich nicht auf die enumeraetion um zwischen zwei sebsequent Aufzählungen verlassen? Gegeben, es gibt keine Einfügungen oder Entfernungen.

Zum Beispiel können sagen, ich habe einige Elemente zu einem HashSet hinzugefügt:

HashSet<int> set = new HashSet<int>(); 
set.Add(1); 
set.Add(2); 
set.Add(3); 
set.Add(4); 
set.Add(5); 

Nun, wenn ich diesen Satz über foreach aufzählen, lassen Sie uns sagen, dass ich erhalten diese Sequenz:

// Result: 1, 3, 4, 5, 2. 

Die Frage ist: Bleibt die Reihenfolge erhalten, wenn ich das Set wieder aufzähle, da ich keine Einfügungen/Entnahmen mache? Wird es immer gleich sein?

+5

Auch wenn dies zutrifft, hätte dies dokumentiert werden müssen. Da es nicht ist, würde ich mich nicht darauf verlassen. Es könnte jederzeit mit einem zukünftigen Update des Frameworks in Ihrem Gesicht brechen. Warum in der Welt würden Sie einen Hash verwenden, wenn Sie eine garantierte Aufzählungsreihenfolge benötigen. Das ist absolut die falsche Datenstruktur, die Sie gewählt haben, um Ihre Daten entsprechend Ihren Anforderungen zu modellieren. –

+1

Da ein Hash-Set grundsätzlich eine Hash-Tabelle ist, die eine feste Slot-Reihenfolge hat, ja, ist die Iterationsreihenfolge konstant, wenn Sie das Set überhaupt nicht ändern. Sollten Sie sich darauf verlassen? Nein, ich denke nicht, du solltest es vermeiden, darauf angewiesen zu sein. – poke

+0

Nun, ich versuche mich nur auf die Reihenfolge von zwei aufeinanderfolgenden Enumerationen eines Satzes zu verlassen, das ist alles. Die Datenstruktur, die ich brauche, ist O (1) add/remove plus die positive Antwort auf die obige Frage. Gibt es irgendwelche? – AgentFire

Antwort

2

In der Praxis könnte es zwischen Aufzählungen immer gleich sein, aber diese Annahme ist in der Beschreibung von IEnumerable nicht vorgesehen und der Implementierer könnte entscheiden, in der gewünschten Reihenfolge zurückzukehren.

Wer weiß, was es unter der Haube tut, und ob es in Zukunft genauso weitermachen wird. Zum Beispiel könnte eine zukünftige Implementierung von HashSet optimiert werden, um Zustände mit wenig Speicher zu erkennen und deren Inhalt im Speicher neu anzuordnen, wodurch die Reihenfolge beeinflusst wird, in der sie zurückgegeben werden. In 99,9% der Fälle würden sie also in derselben Reihenfolge zurückkommen, aber wenn Sie damit beginnen würden, Speicherressourcen auszuschöpfen, würden die Dinge plötzlich in einer anderen Reihenfolge zurückgegeben.

Fazit ist, ich würde nicht auf die Reihenfolge der Aufzählung im Laufe der Zeit konsistent verlassen. Wenn die Bestellung für Sie wichtig ist, dann führen Sie Ihre foreach über set.OrderBy(x => x), so dass Sie sicherstellen können, dass es in der gewünschten Reihenfolge ist.