Question

Pouvez-vous expliquer quelle est la différence entre HashSet<T> et List<T> dans .net?

Peut-être que vous pouvez expliquer avec un exemple dans quels cas HashSet<T> devrait être préféré contre List<T> ?

Était-ce utile?

La solution

Contrairement à une liste <> ...

  1. Un hashset est une liste sans membres en double.

  2. Parce qu'un hashset est contraint de ne contenir que des entrées uniques, la structure interne est optimisée pour la recherche (par rapport à une liste) - elle est considérablement plus rapide

  3. Ajout à un hashset renvoie un booléen - false si l'ajout échoue en raison de déjà existant dans l'ensemble

  4. Peut effectuer des opérations d'ensemble mathématique contre un ensemble: Union / intersection / issubsetof etc.

  5. HashSet n'implémente pas ILIST uniquement icollection

  6. Vous ne pouvez pas utiliser des indices avec un hashset, uniquement des énumérateurs.

La raison principale d'utiliser un HashSet serait si vous souhaitez effectuer des opérations de set.

Étant donné 2 ensembles: hashset1 et hashset2

 //returns a list of distinct items in both sets
 HashSet set3 = set1.Union( set2 );

mouche en comparaison avec une opération équivalente utilisant LINQ. C'est aussi plus net pour écrire!

Autres conseils

UN HashSet<T> est une classe conçue pour vous donner O(1) Recherchez le confinement (c'est-à-dire que cette collection contient un objet particulier et dites-moi la réponse rapidement).

UN List<T> est une classe conçue pour vous donner une collection avec O(1) un accès aléatoire qui peut se développer dynamiquement (pensez à un tableau dynamique). Vous pouvez tester le confinement dans O(n) Temps (sauf si la liste est triée, vous pouvez faire une recherche binaire dans O(log n) temps).

Peut-être que vous pouvez expliquer avec un exemple dans quels cas HashSet<T> devrait être préféré contre List<T>

Lorsque vous souhaitez tester le confinement dans O(1).

Pour être plus précis, démontre avec des exemples,

Vous ne pouvez pas utiliser HashSet comme dans l'exemple suivant.

HashSet<string> hashSet1 = new HashSet<string>(){"1","2","3"};
for (int i = 0; i < hashSet1.Count; i++)
    Console.WriteLine(hashSet1[i]);

hashSet1[i] produirait une erreur:

Ne peut pas appliquer l'indexation avec [] à une expression de type 'System.collections.generic.hashset'

Vous pouvez utiliser une déclaration FOREAK:

foreach (var item in hashSet1)
    Console.WriteLine(item);

Vous ne pouvez pas ajouter d'éléments dupliqués à HashSet tandis que la liste vous permet de le faire et pendant que vous ajoutez un élément à HashSet, vous pouvez vérifier ce qui contient l'élément ou non.

HashSet<string> hashSet1 = new HashSet<string>(){"1","2","3"};
if (hashSet1.Add("1"))
   Console.WriteLine("'1' is successfully added to hashSet1!");
else
   Console.WriteLine("'1' could not be added to hashSet1, because it contains '1'");

Hashset a des fonctions utiles comme IntersectWith, UnionWith, IsProperSubsetOf, ExceptWith, SymmetricExceptWith etc.

IsProperSubsetOf:

HashSet<string> hashSet1 = new HashSet<string>() { "1", "2", "3", "4" };
HashSet<string> hashSet2 = new HashSet<string>() { "2", "4", "6", "8" };
HashSet<string> hashSet3 = new HashSet<string>() { "1", "2", "3", "4", "5" };
if (hashSet1.IsProperSubsetOf(hashSet3))
    Console.WriteLine("hashSet3 contains all elements of hashSet1.");
if (!hashSet1.IsProperSubsetOf(hashSet2))
    Console.WriteLine("hashSet2 does not contains all elements of hashSet1.");

UnionWith:

HashSet<string> hashSet1 = new HashSet<string>() { "3", "4" };
HashSet<string> hashSet2 = new HashSet<string>() { "2", "4", "6", "8" };
hashSet1.UnionWith(hashSet2); //hashSet1 -> 3, 2, 4, 6, 8

IntersectWith:

HashSet<string> hashSet1 = new HashSet<string>() { "3", "4", "8" };
HashSet<string> hashSet2 = new HashSet<string>() { "2", "4", "6", "8" }
hashSet1.IntersectWith(hashSet2);//hashSet1 -> 4, 8

ExceptWith :

 HashSet<string> hashSet1 = new HashSet<string>() { "1", "2", "3", "5", "6" };
 HashSet<string> hashSet2 = new HashSet<string>() { "1", "2", "3", "4" };
 hashSet1.ExceptWith(hashSet2);//hashSet1 -> 5, 6

SymmetricExceptWith :

 HashSet<string> hashSet1 = new HashSet<string>() { "1", "2", "3", "5", "6" };
 HashSet<string> hashSet2 = new HashSet<string>() { "1", "2", "3", "4" };
 hashSet1.SymmetricExceptWith(hashSet2);//hashSet1 -> 4, 5, 6

Soit dit en passant, l'ordre n'est pas conservé dans les hachages. Dans l'exemple, nous avons ajouté l'élément "2" en dernier mais c'est dans le second ordre:

HashSet<string> hashSet1 = new HashSet<string>() { "3", "4", "8" };
hashSet1.Add("1");    // 3, 4, 8, 1
hashSet1.Remove("4"); // 3, 8, 1
hashSet1.Add("2");    // 3, 2 ,8, 1

Utiliser un List<T> quand tu veux:

  • Stockez une collection d'articles dans une certaine commande.

Si vous connaissez l'index de l'élément que vous souhaitez (plutôt que la valeur de l'élément lui-même) O(1). Si vous ne connaissez pas l'index, trouver l'article prend plus de temps, O(n) pour une collection non triée.

Utiliser un Hashset<T> quand tu veux:

  • Découvrez rapidement si un certain objet est contenu dans une collection.

Si vous connaissez le nom de la chose que vous voulez trouver, la recherche est O(1) (C'est la partie «hachage»). Il ne maintient pas une commande comme le List<T> FAIT et vous ne pouvez pas stocker des doublons (l'ajout d'un double n'a aucun effet, c'est la pièce «set»).

Un exemple de quand utiliser un Hashset<T> Ce serait si vous voulez savoir si un mot joué dans un jeu de Scrabble est un mot valide en anglais (ou une autre langue). Encore mieux serait si vous vouliez créer un service Web à utiliser par tous les cas d'une version en ligne d'un tel jeu.

UN List<T> Ce serait une bonne structure de données pour créer le tableau de bord pour suivre les scores des joueurs.

La liste est une liste commandée. Il est

  • accessible par un index entier
  • peut contenir des doublons
  • a un ordre prévisible

HashSet est un ensemble. Ce:

  • Peut bloquer les articles en double (voir Ajoutez t))
  • Ne garantit pas l'ordre des articles dans l'ensemble
  • A des opérations que vous attendez sur un ensemble, par exemple, Intersect avec, ispropersubsetof, UnionWith.

La liste est plus appropriée lorsque vous souhaitez accéder à votre collection comme s'il s'agissait d'un tableau auquel vous pouvez ajouter, insérer et supprimer les éléments. HashSet est un meilleur choix si vous souhaitez traiter votre collection comme un "sac" d'articles dans lesquels l'ordre n'est pas important ou lorsque vous souhaitez le comparer avec d'autres ensembles en utilisant les opérations telles que intersect avec ou Union avec.

La liste n'est pas nécessairement unique, tandis que Hashset est, pour un.

Une liste est une collection commandée d'objets de type T qui, contrairement à un tableau, vous pouvez ajouter et supprimer les entrées.

Vous utiliseriez une liste où vous souhaitez référencer les membres dans l'ordre que vous les avez stockés et vous y accédez par un poste plutôt que par l'élément lui-même.

Un hashset est comme un dictionnaire que l'élément lui-même est la clé ainsi que la valeur, la commande n'est pas garantie.

Vous utiliseriez un hashset où vous souhaitez vérifier qu'un objet se trouve dans la collection

Si vous décidez d'appliquer ces structures de données à l'utilisation réelle du développement basé sur les données, un hashset est très utile pour tester la réplication par rapport aux sources d'adaptateur de données, pour le nettoyage et la migration des données.

De plus, si vous utilisez la classe Dataannotations, on peut implémenter une logique clé sur les propriétés de classe et contrôler efficacement un index naturel (en cluster ou non) avec un hashset, où cela serait très difficile dans une implémentation de liste.

Une option forte pour utiliser une liste consiste à implémenter des génériques pour plusieurs supports sur un modèle de vue, tels que l'envoi d'une liste de classes à une vue MVC pour une aide Dropdown, et également pour l'envoi en tant que construction JSON via WebAPI. La liste permet une logique de collecte de classe typique et maintient la flexibilité pour une approche plus "interface" pour calculer un modèle de vue unique à différents supports.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top