web-dev-qa-db-fra.com

Collection C # Set?

Est-ce que quelqu'un sait s'il existe un bon équivalent à la collection Set de Java en C #? Je sais que vous pouvez imiter un ensemble en utilisant un Dictionary ou un HashTable en le renseignant mais en ignorant les valeurs, mais ce n'est pas une manière très élégante.

454
Omar Kooheji

Essayez HashSet :

La classe HashSet (Of T) fournit des opérations d'ensemble performantes. Un ensemble est une collection qui ne contient aucun élément dupliqué et dont les éléments ne sont dans aucun ordre particulier ...

La capacité d'un objet HashSet (Of T) est le nombre d'éléments que l'objet peut contenir. La capacité d'un objet HashSet (Of T) augmente automatiquement à mesure que des éléments sont ajoutés à l'objet.

La classe HashSet (Of T) est basée sur le modèle des ensembles mathématiques et fournit des opérations sur les ensembles hautes performances similaires à l'accès aux clés de Dictionary (Of TKey, TValue) ou Hashtable collections. En termes simples, la classe HashSet (Of T) peut être considérée comme une collection Dictionary (Of TKey, TValue) sans valeurs.

Une collection HashSet (Of T) n'est pas triée et ne peut pas contenir d'éléments en double ...

112
Leahn Novash

Si vous utilisez .NET 3.5, vous pouvez utiliser HashSet<T> . Il est vrai que .NET ne gère pas les ensembles aussi bien que Java.

Le Wintellect PowerCollections peut aussi aider.

404
Jon Skeet

La structure de données _HashSet<T>_:

La structure de données _HashSet<T>_ de la bibliothèque de classes Framework a été introduite dans le .NET Framework 3.5. Une liste complète de ses membres est disponible sur le page de référence MSDN pour _HashSet<T>_ .

_HashSet<T>_ est plus ou moins calqué sur un ensemble mathématique , ce qui signifie que:

  1. Il ne peut contenir aucune valeur en double.

  2. Ses éléments ne sont dans aucun ordre particulier; par conséquent, le type n'implémente pas l'interface IList<T> , mais l'interface plus fondamentale ICollection<T> . Par conséquent, les éléments d’un ensemble de hachages ne peuvent pas être consultés de manière aléatoire au moyen d’index; ils ne peuvent être parcourus que par un enquêteur.

  3. Certaines fonctions définies telles que Union, Intersection, IsSubsetOf, IsSupersetOf sont disponibles. Ceux-ci peuvent être utiles lorsque vous travaillez avec plusieurs ensembles.

Une autre différence entre _HashSet<T>_ et _List<T>_ est que l'appel de la méthode Add(item) d'un ensemble de hachages renvoie une valeur booléenne: true si l'élément a été ajouté, et false sinon ( car il a déjà été trouvé dans le jeu).

Pourquoi pas _List<T>_?

Etant donné qu'un _HashSet<T>_ est simplement une collection d'objets uniques, vous pouvez vous demander pourquoi il doit s'agir d'une structure de données. Un _List<T>_ normal pourrait avoir le même comportement en vérifiant si un objet est trouvé dans la liste avant de l'ajouter.

La réponse courte est la vitesse. La recherche dans un _List<T>_ normal devient très lente, car de nouveaux éléments sont ajoutés. Un _HashSet<T>_ nécessite une conception de structure permettant une recherche rapide et des vitesses d'insertion.

Points de repère:

Comparons la vitesse d'exécution d'un _HashSet<T>_ à un _List<T>_.

Chaque essai consistait à ajouter des nombres entiers allant de 0 à 9 999 à chaque collection. Cependant, le mod 25 a été appliqué à chaque entier. Le mod 25 permet d'obtenir le maximum de types d'éléments 25. Comme 10 000 éléments ont été ajoutés, 400 collisions ont été forcées, ce qui a permis aux structures de données d'utiliser leurs algorithmes de recherche. Les temps ont été mesurés 3 fois après 10 000 essais et moyennés.

Ne faites pas trop attention aux durées d'exécution spécifiques des tests car ils dépendent de mon matériel, mais regardez comment ils se comparent les uns aux autres.

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

Faisons maintenant des objets éléments au lieu de types primitifs. J'ai écrit une classe rapide Person avec trois champs: Name, LastName et ID. Étant donné que je n'ai inclus aucun moyen spécifique de comparer des objets, tous les éléments seront ajoutés sans collision. Cette fois, 1 000 objets Person ont été ajoutés à chaque collection pour un seul essai. Les temps totaux de 3 séries de 1 000 essais ont été moyennés.

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

Comme vous pouvez le constater, la différence de temps de fonctionnement devient astronomique lors de l’utilisation d’objets, ce qui rend le _HashSet<T>_ avantageux.

119

Si vous utilisez .NET 4.0 ou version ultérieure:

Dans le cas où vous avez besoin de trier, utilisez SortedSet<T> . Sinon, sinon, utilisez HashSet<T> puisqu'il s'agit de O(1) pour les opérations de recherche et de manipulation. Alors que _SortedSet<T>_ est O(log n) pour les opérations de recherche et de manipulation.

19
Derek W

J'utilise Iesi.Collections http://www.codeproject.com/KB/recipes/sets.aspx

Il est utilisé dans de nombreux projets OSS, je l'ai découvert pour la première fois dans NHibernate.

14
Chris Canal

J'utilise un wrapper autour d'un Dictionary<T, object>, stockant les valeurs null dans les valeurs. Cela donne O(1) ajouter, rechercher et supprimer des clés, et à toutes fins utiles, il agit comme un ensemble.

12
thecoop

Jetez un oeil à PowerCollections sur CodePlex. En plus de Set et OrderedSet, il possède quelques autres types de collections utiles tels que Deque, MultiDictionary, Bag, OrderedBag, OrderedDictionary et OrderedMultiDictionary.

Pour plus de collections, il y a aussi le Bibliothèque de collections génériques C5 .

11
dpan

Vous pouvez implémenter votre propre implémentation d'ensembles réalisable en quelques heures. Je l'ai utilisé quand je devais le faire (désolé, je n'ai pas le code à portée de main): http://Java.Sun.com/j2se/1.4.2/docs/api/Java/util/ Set.html

0
cciotti