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.
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 ...
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.
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:
Il ne peut contenir aucune valeur en double.
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.
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.
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.
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.
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.
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 .
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