Question Array versus List : quand utiliser lequel?


MyClass[] array;
List<MyClass> list;

Quels sont les scénarios quand l'un est préférable à l'autre? Et pourquoi?


480
2018-01-12 08:08


origine


Réponses:


Il est rare, en réalité, que vous vouliez utiliser un tableau. Définitivement utiliser un List<T> chaque fois que vous voulez ajouter / supprimer des données, car le redimensionnement des tableaux est coûteux. Si vous savez que les données sont de longueur fixe, et que vous voulez micro-optimiser pour certains Très spécifique raison (après l'analyse comparative), un tableau peut être utile.

List<T> offre un lot plus de fonctionnalités qu’un tableau (bien que LINQ l’a un peu amélioré), et c’est presque toujours le bon choix. À l'exception de params arguments, bien sûr. ;-p

Comme un compteur - List<T> est unidimensionnel; où-comme vous avez des tableaux rectangulaires (etc) comme int[,] ou string[,,] - mais il existe d'autres moyens de modéliser de telles données (si vous en avez besoin) dans un modèle d'objet.

Voir également:

Cela dit, je fais un lot d'utilisation de tableaux dans mon protobuf-net projet; entièrement pour la performance:

  • il fait beaucoup de décalage, donc un byte[] est quasiment indispensable pour l'encodage;
  • J'utilise un roulement local byte[] tampon que je remplis avant de l'envoyer au flux sous-jacent (et v.v.); plus vite que BufferedStream etc;
  • il utilise en interne un modèle d'objets basé sur un tableau (Foo[] plutôt que List<Foo>), puisque la taille est fixée une fois construite, et doit être très rapide.

Mais c'est définitivement une exception; pour le traitement général des secteurs d'activité, un List<T> gagne à chaque fois.


462
2018-01-12 08:10



Vraiment juste répondre pour ajouter un lien que je suis surpris n'a pas encore été mentionné: le blog d'Eric Lippert sur "Les tableaux considérés comme quelque peu nocifs."

Vous pouvez juger du titre qu'il est suggérant l'utilisation des collections quand cela est possible - mais comme Marc souligne à juste titre, il y a beaucoup d'endroits où un tableau est vraiment la seule solution pratique.


106
2018-01-12 08:26



Utilisez un tableau lorsque vous traitez des données qui sont:

  • fixé en taille, ou peu susceptible de grandir beaucoup
  • suffisamment grand (plus de 10, 50, 100 éléments, selon l'algorithme)
  • vous allez faire beaucoup d'indexation en elle, à savoir que vous savez que vous aurez souvent l'élément troisième ou cinquième, ou autre chose.

Utilisez une liste pour:

  • listes de données de longueur variable
  • qui sont principalement utilisés comme une pile ou une file d'attente ou doivent être itérés dans leur intégralité
  • quand vous ne voulez pas écrire une expression pour calculer la taille du tableau final pour la déclaration et vous ne voulez pas choisir gaspillée un grand nombre

Utilisez un hashmap pour:

  • listes de données de longueur variable
  • qui ont besoin d'être indexé comme un tableau

En réalité, vous aurez besoin d'une liste ou hashmap presque tout le temps. La prochaine fois que vous choisirez une structure de données, réfléchissez à ce qu’elle doit bien faire pour vous (ou votre code, de toute façon). Ensuite, choisissez quelque chose basé sur cela. En cas de doute, choisissez quelque chose d'aussi général que possible, c'est-à-dire une interface que vous pouvez facilement remplacer. Quelques bons liens dans les autres réponses aussi bien.


41
2018-01-12 08:37



Nonobstant les autres réponses recommandant List<T>, vous voudrez utiliser des tableaux lors de la manipulation:

  • données bitmap d'image
  • d'autres structures de données de bas niveau (c'est-à-dire des protocoles réseau)

17
2018-01-12 08:16



A moins que vous ne soyez vraiment concerné par la performance, et par là je veux dire, "Pourquoi utilisez-vous .Net au lieu de C ++?" vous devriez vous en tenir à la liste <>. C'est plus facile à maintenir et fait tout le sale boulot de redimensionner un tableau derrière la scène pour vous. (Si nécessaire, List <> est assez intelligent pour choisir les tailles de tableau, donc il n'a pas besoin d'habitude.)


9
2018-01-12 08:12



Tableaux devrait être utilisé de préférence à List lorsque l'immutabilité de la collection elle-même fait partie du contrat entre le code client et le code fournisseur (pas nécessairement l'immutabilité des articles dans la collection) ET quand IEnumerable ne convient pas.

Par exemple,

var str = "This is a string";
var strChars = str.ToCharArray();  // returns array

Il est clair que la modification de "strChars" ne mutera pas l'objet "str" ​​d'origine, quelle que soit la connaissance au niveau de l'implémentation du type sous-jacent de "str".

Mais supposons que

var str = "This is a string";
var strChars = str.ToCharList();  // returns List<char>
strChars.Insert(0, 'X');

Dans ce cas, il n’est pas clair à partir de cet extrait de code seul si la méthode d’insertion modifie ou non l’objet «str» original. Il nécessite une connaissance du niveau d'implémentation de String pour effectuer cette détermination, ce qui casse l'approche Design by Contract. Dans le cas de String, ce n'est pas une grosse affaire, mais cela peut être un gros problème dans presque tous les autres cas. Définir la liste en lecture seule ne permet que des erreurs d'exécution, pas de compilation.


6
2018-03-05 01:37



Si je sais exactement de combien d'éléments je vais avoir besoin, disons que j'ai besoin de 5 éléments et seulement déjà 5 éléments alors j'utilise un tableau. Sinon, j'utilise simplement une liste <T>.


3
2018-01-12 08:37



La plupart du temps, en utilisant un List suffirait. UNE List utilise un tableau interne pour gérer ses données et redimensionne automatiquement le tableau lors de l'ajout d'éléments List que sa capacité actuelle, ce qui le rend plus facile à utiliser qu’un réseau, où vous devez connaître la capacité au préalable.

Voir http://msdn.microsoft.com/en-us/library/ms379570(v=vs.80).aspx#datastructures20_1_topic5 pour plus d'informations sur les listes en C # ou simplement décompiler System.Collections.Generic.List<T>.

Si vous avez besoin de données multidimensionnelles (par exemple, en utilisant une matrice ou une programmation graphique), vous irez probablement avec un array au lieu.

Comme toujours, si la mémoire ou la performance est un problème, mesurez-le! Sinon, vous pourriez faire de fausses hypothèses sur le code.


3
2017-11-23 09:45



Une autre situation non encore mentionnée est celle où l'on aura un grand nombre d'éléments, dont chacun consiste en un groupe fixe de variables liées mais indépendantes, collées ensemble (par exemple les coordonnées d'un point, ou les sommets d'un triangle 3d). Un tableau de structures de champ exposé permettra de modifier efficacement ses éléments "en place", ce qui n'est pas possible avec un autre type de collection. Comme un tableau de structures conserve consécutivement ses éléments dans la RAM, les accès séquentiels aux éléments du tableau peuvent être très rapides. Dans les situations où le code devra faire de nombreux passages séquentiels à travers un tableau, un tableau de structures peut dépasser un tableau ou une autre collection de références d'objet de classe d'un facteur de 2: 1; de plus, la possibilité de mettre à jour des éléments en place peut permettre à un ensemble de structures de surpasser tout autre type de collection de structures.

Bien que les tableaux ne soient pas redimensionnables, il n'est pas difficile d'avoir du code stockant une référence de tableau avec le nombre d'éléments utilisés, et de remplacer le tableau par un plus grand, selon les besoins. Alternativement, on pourrait facilement écrire du code pour un type qui se comporte beaucoup comme un List<T> mais exposé son magasin de soutien, permettant ainsi de dire soit MyPoints.Add(nextPoint); ou MyPoints.Items[23].X += 5;. Notez que cette dernière ne déclencherait pas nécessairement une exception si le code tentait d’accéder au-delà de la fin de la liste, mais que l’utilisation serait sinon conceptuellement assez similaire à List<T>.


1
2017-08-21 21:17



Les listes dans .NET sont des wrappers sur des tableaux et utilisent un tableau en interne. La complexité temporelle des opérations sur les listes est la même que celle des tableaux, mais il y a un peu plus de surcharge avec toutes les fonctionnalités / facilité d'utilisation des listes ajoutées (telles que le redimensionnement automatique et les méthodes fournies avec la classe list). À peu près, je recommande d'utiliser des listes dans tous les cas, sauf s'il y a une raison impérieuse ne pas Pour ce faire, par exemple, si vous avez besoin d'écrire du code extrêmement optimisé ou si vous travaillez avec d'autres codes construits autour de tableaux.


1
2017-07-09 05:39