2008-10-02 7 views
9

Que recommanderiez-vous à la classe qui doit conserver une liste d'entiers uniques?Classe .NET recommandée pour une collection d'entiers uniques?

Je vais vouloir ajouter des entiers() à la collection et vérifier l'existence par ex. Contient().

Serait agréable de les obtenir également dans une liste comme une chaîne pour l'affichage, à savoir. "1, 5, 10, 21".

+1

Désolé je n'ai pas spécifié. Je peux utiliser le dernier cadre. 3.5 mais vos réponses peuvent aider d'autres personnes à ne pas utiliser les dernières. –

Répondre

24

HashSet:

La classe HashSet<T> fournit des opérations de réglage haute performance. Un ensemble est une collection qui ne contient aucun élément en double et dont les éléments ne sont pas dans un ordre particulier ...

La capacité d'un objet HashSet<T> est le nombre d'éléments que l'objet peut contenir. La capacité de l'objet HashSet<T> augmente automatiquement à mesure que des éléments sont ajoutés à l'objet. La classe HashSet<T> est basée sur le modèle d'ensembles mathématiques et fournit des opérations d'ensemble hautes performances similaires à l'accès aux clés des collections Dictionary<TKey, TValue> ou Hashtable. En termes simples, la classe HashSet<T> peut être considérée comme une collection Dictionary<TKey, TValue> sans valeurs.

Une collection HashSet<T> ne sont pas triées et ne peut pas contenir des éléments en double ...

+0

J'ai regardé l'arraylist et c'est certainement mieux que l'arraylist, donc j'ai enlevé ma réponse précédente. – EBGreen

+1

HashSet va ToString le type ... pas une liste. Et la liste qu'il affiche est une commande, que HashSet ne supporte pas. – MagicKat

+0

Correct. Pour obtenir la liste des chaînes, vous devez utiliser le code suivant: int [] a = h.ToArray (); Tableau.Sort (a); string.Join (',', a); Ce n'est pas une haute performance, mais j'ai l'impression que ce n'est pas une opération courante, et c'est plus pour le débogage/visualisation que pour le calcul. –

2

Si vous ne pouvez pas utiliser .NET 3.5, vous ne pouvez pas utiliser HashSet. Si c'est le cas, il est facile de rouler les vôtres en fonction de la structure du dictionnaire.

public class Set<T> { 
    private class Unit { ... no behavior } 
    private Dictionary<T, Unit> d; 

.... 
} 

L'unité est destinée à être un type avec exactement une valeur. Peu importe ce que vous mappez les éléments à, utilisez simplement les touches pour savoir ce qu'il y a dans votre décor. Les opérations que vous avez demandées dans la question sont simples à mettre en œuvre.

+1

Pourquoi même créer des classes 'Unit'? La valeur peut être 'null'. –

+0

Quel serait le type? "objet"? – EfForEffort

+1

Oui, le dictionnaire fonctionnerait bien pour cela. –

1

vous pourriez hériter d'une classe de KeyedCollection. De cette façon, votre clé peut être la valeur elle-même, vous pouvez remplacer ToString pour obtenir la sortie désirée. Cela pourrait vous donner le comportement que vous voulez/avez besoin.

Notez cette réponse a été pour la partie framework 2.0 du Q

3

Dans mes tests, j'ai trouvé qu'un dictionnaire avec une valeur factice est plus rapide qu'un HashSet, lorsqu'ils traitent avec des ensembles de données très volumineux (100 000+ dans mon cas). Je pense que c'est parce que le dictionnaire vous permet de définir une capacité initiale, mais je ne sais pas vraiment. Dans le cas que vous décrivez, j'utiliserais probablement le dictionnaire si j'attendais un très grand nombre de nombres, et puis (ou comme j'ajoutais au dictionnaire, selon l'intention) itérer dessus à l'aide d'un constructeur de chaîne, pour créer la chaîne de sortie.

Questions connexes