it-swarm.com.de

C # Set Sammlung?

Weiß jemand, ob es eine gute Entsprechung zu Javas Set -Auflistung in C # gibt? Ich weiß, dass Sie eine Menge mit Dictionary oder HashTable etwas imitieren können, indem Sie die Werte auffüllen, aber ignorieren, aber das ist keine sehr elegante Art und Weise.

454
Omar Kooheji

Versuchen Sie HashSet :

Die HashSet (Of T) -Klasse bietet leistungsstarke Mengenoperationen. Ein Set ist eine Sammlung, die keine doppelten Elemente enthält und deren Elemente sich in keiner bestimmten Reihenfolge befinden ...

Die Kapazität eines HashSet (Of T) -Objekts ist die Anzahl der Elemente, die das Objekt enthalten kann. Die Kapazität eines HashSet (Of T) -Objekts erhöht sich automatisch, wenn dem Objekt Elemente hinzugefügt werden.

Die HashSet (Of T) -Klasse basiert auf dem Modell mathematischer Mengen und bietet leistungsstarke Mengenoperationen, die dem Zugriff auf die Schlüssel des Dictionary (Of TKey, TValue) oder Hashtable Sammlungen. In einfachen Worten kann die HashSet (Of T) -Klasse als Dictionary (Of TKey, TValue) - Auflistung ohne Werte betrachtet werden.

Eine HashSet (Of T) -Sammlung ist nicht sortiert und kann keine doppelten Elemente enthalten ...

112
Leahn Novash

Wenn Sie .NET 3.5 verwenden, können Sie HashSet<T> verwenden. Es ist wahr, dass .NET nicht so gut für Mengen geeignet ist wie Java.

Die Wintellect PowerCollections können ebenfalls helfen.

404
Jon Skeet

Die _HashSet<T>_ Datenstruktur:

Die Datenstruktur der Framework-Klassenbibliothek _HashSet<T>_ wurde in .NET Framework 3.5 eingeführt. Eine vollständige Liste der Mitglieder finden Sie auf der MSDN-Referenzseite für _HashSet<T>_ .

_HashSet<T>_ ist mehr oder weniger nach einem mathematischen Satz modelliert, was bedeutet, dass:

  1. Es darf keine doppelten Werte enthalten.

  2. Seine Elemente sind in keiner bestimmten Reihenfolge; Daher implementiert der Typ nicht die Schnittstelle IList<T> , sondern die grundlegendere ICollection<T> . Infolgedessen kann auf Elemente innerhalb einer Hash-Menge nicht über Indizes zufällig zugegriffen werden. Sie können nur durch einen Enumerator durchlaufen werden.

  3. Bestimmte eingestellte Funktionen wie Union, Intersection, IsSubsetOf, IsSupersetOf sind verfügbar. Diese können nützlich sein, wenn Sie mit mehreren Sets arbeiten.

Ein weiterer Unterschied zwischen _HashSet<T>_ und _List<T>_ besteht darin, dass beim Aufrufen der Methode Add(item) eines Hash-Sets ein boolescher Wert zurückgegeben wird: true, wenn das Element hinzugefügt wurde, und false, andernfalls ( denn es wurde bereits im Set gefunden).

Warum nicht _List<T>_?

Da ein _HashSet<T>_ einfach eine Sammlung eindeutiger Objekte ist, fragen Sie sich möglicherweise, warum es sich um eine Datenstruktur handeln muss. Ein normaler _List<T>_ kann dasselbe Verhalten aufweisen, indem geprüft wird, ob ein Objekt in der Liste gefunden wurde, bevor es hinzugefügt wird.

Die kurze Antwort lautet Geschwindigkeit. Das Durchsuchen eines normalen _List<T>_ wird sehr langsam, sehr schnell, wenn mehr Elemente hinzugefügt werden. Ein _HashSet<T>_ erfordert ein Strukturdesign, das schnelle Such- und Einfügungsgeschwindigkeiten ermöglicht.

Benchmarks:

Vergleichen wir die Geschwindigkeit eines _HashSet<T>_ mit einer _List<T>_.

Jeder Versuch bestand aus dem Hinzufügen von ganzen Zahlen von 0 bis 9.999 zu jeder Sammlung. Mod 25 wurde jedoch auf jede ganze Zahl angewendet. Mit Mod 25 werden die maximalen Elementtypen 25 erstellt. Da 10.000 Elemente hinzugefügt wurden, mussten 400 Kollisionen auftreten, sodass die Datenstrukturen ihre Suchalgorithmen verwenden konnten. Die Zeiten wurden nach 10.000 Versuchen dreimal gemessen und gemittelt.

Achten Sie nicht zu sehr auf die spezifischen Laufzeiten der Tests, da sie von meiner Hardware abhängen, sondern schauen Sie sich an, wie sie sich vergleichen.

_           Average time [ms]
----------------------------
HashSet<T>             2,290
List<T>                5,505
_

Lassen Sie uns nun Elemente anstelle von primitiven Typen erstellen. Ich habe eine schnelle Person Klasse mit drei Feldern geschrieben: Name, LastName und ID. Da ich keine bestimmte Methode zum Vergleichen von Objekten angegeben habe, werden alle Elemente ohne Kollisionen hinzugefügt. Dieses Mal wurden jeder Sammlung 1.000 Person Objekte für einen einzelnen Versuch hinzugefügt. Die Gesamtzeiten von 3 Sätzen mit 1.000 Versuchen wurden gemittelt.

_           Average time [ms]
----------------------------
HashSet<Person>          201
List<Person>           3,000
_

Wie Sie sehen, wird der Unterschied in den Laufzeiten bei der Verwendung von Objekten astronomisch, wodurch der Vorteil von _HashSet<T>_ entsteht.

119

Wenn Sie .NET 4.0 oder höher verwenden:

Wenn Sie sortieren müssen, verwenden Sie SortedSet<T> . Andernfalls verwenden Sie HashSet<T> , da es sich um O(1) für Such- und Manipulationsvorgänge handelt. Während _SortedSet<T>_ für Such- und Manipulationsoperationen O(log n) ist.

19
Derek W

Ich benutze Iesi.Collections http://www.codeproject.com/KB/recipes/sets.aspx

Es wird in vielen OSS-Projekten verwendet und ist mir zum ersten Mal in NHibernate begegnet

14
Chris Canal

Ich benutze einen Wrapper um einen Dictionary<T, object>, der Nullen in den Werten speichert. Dies gibt O(1) Addieren, Nachschlagen und Entfernen auf den Schlüsseln und verhält sich in jeder Hinsicht wie eine Menge.

12
thecoop

Schauen Sie sich PowerCollections bei CodePlex an. Neben Set und OrderedSet gibt es noch einige andere nützliche Sammlungstypen wie Deque, MultiDictionary, Bag, OrderedBag, OrderedDictionary und OrderedMultiDictionary.

Für weitere Sammlungen gibt es auch die C5 Generic Collection Library .

11
dpan

Sie können Ihre eigene funktionsfähige Mengenimplementierung in wenigen Stunden implementieren. Ich habe dies verwendet, als ich es tun musste (sorry, ich habe den Code nicht zur Hand): http://Java.Sun.com/j2se/1.4.2/docs/api/Java/util/ Set.html

0
cciotti