74 votes

Pourquoi ne Énumération converties liste de tableaux et de ne pas Liste dans java.utils?

Est-il une bonne raison que les Collections.liste() la méthode dans l' java.utils de retour de colis un ArrayList<T> au lieu de List<T>?

Bien évidemment, une ArrayList est List, mais j'ai l'impression que c'est généralement une bonne pratique pour retourner le type d'interface au lieu de la mise en œuvre de type.

54voto

durron597 Points 9165

Avertissement: je ne suis pas un JDK auteur.

Je suis d'accord que c'est correct d'écrire votre propre code pour les interfaces, mais si vous allez retourner une mutable collection à un tiers, il est important de laisser le tiers de savoir de quel type d' List qu'ils obtiennent en retour.

LinkedList et ArrayList sont très différentes, la performance sage, pour diverses opérations. Par exemple, la suppression du premier élément d'un ArrayList est O(n), mais de supprimer le premier élément d'un LinkedList est O(1).

En mettant pleinement en spécifiant le type de retour, le JDK auteurs sont à communiquer des informations supplémentaires, sans ambiguïté code, sur ce genre d'objet qu'ils sont de donner en retour à vous, vous pouvez écrire votre code pour utiliser cette méthode correctement. Si vous avez vraiment besoin d'un LinkedList, vous savez que vous devez le spécifier ici.

Enfin, la principale raison de coder une interface plus d'une mise en œuvre est si vous pensez que la mise en œuvre du changement. Le JDK auteurs probablement la figure, ils sont jamais va changer cette méthode; il ne va jamais revenir un LinkedList ou Collections.UnmodifiableList. Cependant, dans la plupart des cas, vous n'auriez sans doute encore à faire:

List<T> list = Collections.list(enumeration);

32voto

Maroun Maroun Points 31217

Lors du retour de la List, vous serez la promotion du programme à une interface, qui est une très bonne pratique. Cependant, cette approche a ses limites. Par exemple, vous ne pouvez pas utiliser certaines des méthodes qui sont définies pour ArrayList et n'existent pas dans l' List interface - Voir cette réponse pour plus de détails.

Je cite la Conception d'API à partir de la Java™ Tutoriels:

... C'est bien de renvoyer un objet de n'importe quel type qui implémente ou s'étend l'une des interfaces de collection. Cela peut être l'une des interfaces ou à un usage spécial de type qui s'étend ou met en œuvre l'une de ces interfaces.

.. Dans un sens, les valeurs de retour doit avoir le comportement opposé de paramètres d'entrée: C'est mieux pour revenir le plus spécifique applicable interface de collecte plutôt que le plus général. Par exemple, si vous êtes sûr que vous aurez toujours revenir un SortedMap, vous devriez donner la méthode, le type de retour d' SortedMap plutôt que d' Map. SortedMap des occurrences sont plus beaucoup de temps à construire que d'ordinaire, Map des cas et aussi plus puissant. Étant donné que votre module a déjà investi du temps pour construire une SortedMap, il est de bon sens à donner à l'utilisateur l'accès à son augmentation de puissance. En outre, l'utilisateur sera en mesure de passer à l'objet retourné vers des méthodes qui demande un SortedMap, ainsi que ceux qui acceptent tout Map.

Depuis ArrayList est essentiellement un tableau, ils sont mon premier choix quand j'ai besoin d'avoir une "collection-array". Donc, si je veux convertir énumération d'une liste, mon choix serait un tableau de la liste.

Dans tous les autres cas, il est toujours valable pour écrire:

List<T> list = Collections.list(e);

6voto

supercat Points 25534

Les fonctions qui renvoient des "propriété exclusive" de nouvellement créé mutable objets doivent souvent être les plus spécifiques au type de pratique; ceux qui retournent des objets immuables, surtout si elles peuvent être partagées, doit souvent revenir moins des types spécifiques.

La raison de cette distinction est que dans le premier cas, l'objet sera toujours en mesure de produire un nouvel objet du type indiqué, et depuis le destinataire de l'objet et il n'y a pas de raconter ce que les actions que le destinataire peut souhaiter effectuer, il y aurait généralement aucun moyen pour le code de retour de l'objet pour savoir si une alternative implémentations d'interface pourrait fonction des besoins du bénéficiaire.

Dans ce dernier cas, le fait que l'objet est immuable signifie que la fonction peut être en mesure de déterminer un autre type qui peut faire tout ce qu'un plus compliquée pourrait le faire compte tenu de sa teneur exacte. Par exemple, un Immutable2dMatrix interface peut être implémentée par un ImmutableArrayBacked2dMatrix de la classe et un ImmutableDiagonal2dMatrix classe. Une fonction qui est censé renvoyer un carré Immutable2dMatrix pourraient décider d'y retourner un ImmutableDiagonalMatrix exemple si tous les éléments hors de la diagonale principale arriver à zéro, ou un ImmutableArrayBackedMatrix si pas. Le premier type serait prendre beaucoup moins d'espace de stockage, mais le destinataire ne se soucient pas de la différence entre eux.

De retour Immutable2dMatrix plutôt que d'un béton ImmutableArrayBackedMatrix code permet de choisir le type de retour que le tableau contient; cela signifie également que si le code qui est censé renvoyer le tableau se trouve être la tenue d'une mise en œuvre adaptée de l' Immutable2dMatrix il suffit de retourner que, plutôt que d'avoir à construire une nouvelle instance. Ces deux facteurs peuvent être des "victoires" lorsque vous travaillez avec des objets immuables.

Lorsque vous travaillez avec des objets mutables, cependant, aucun facteur entre en jeu. Le fait qu'une mutable tableau pourrait ne pas avoir d'éléments hors de la diagonale principale lorsqu'elle est générée ne signifie pas qu'il n'aura jamais de tels éléments. Par conséquent, si un ImmutableDiagonalMatrix est effectivement un sous-type d'un Immutable2dMatrix, MutableDiagonalMatrix n'est pas un sous-type d'un Mutable2dMatrix, puisque cette dernière pourrait accepter les magasins hors de la diagonale principale, alors que les anciens ne le peuvent pas. De plus, bien que des objets immuables souvent peut et doit être partagé, mutable objets ne peuvent généralement pas. Une fonction qui est demandé pour une nouvelle mutable collection initialisé avec certains contenus aurez besoin pour créer une nouvelle collection si oui ou non son magasin de sauvegarde correspond au type demandé.

1voto

Ian Ringrose Points 19115

Il y a une petite surcharge lors de l'appel de méthodes var une interface plutôt que directement sur un objet.

Cette surcharge de travail est souvent pas plus de 1 ou 2 instructions du processeur. La surcharge de l'appel d'une méthode est encore plus faible si l'équipe sait que la méthode est définitive. Ce n'est pas mesurable pour la plupart des code vous et moi, mais pour le faible niveau des méthodes en java.utils peut être utilisé dans un code où il est un problème.

Également, comme cela a été souligné dans d'autres réponses, le type concret de l'objet qui est de retour (même caché derrière une interface), les effets de la performance de code qui l'utilise. Ce changement dans les performances peuvent être très grand, de sorte que dans une mesure telle que l'appel logiciel ne fonctionne pas.

Clairement les auteurs de l' java.utils n'ont aucun moyen de savoir ce que tous les logiciels qui appelle des Collections.liste() avec le résultat et pas moyen de re-tester ce logiciel s'ils changent de l'implantation des Collections.liste(). Par conséquent, ils ne vont pas changer l'implantation des Collections.liste() pour retourner un autre type de Liste, même si le type de système de permis à!

Lors de l'écriture de votre propre logiciel, vous (espérons-le) de test automatisé, qui couvrent l'ensemble de votre code et une bonne compréhension de la façon dont votre code met en relation inclure savoir où la performance est un problème. Être en mesure de faire un changement de méthode, sans avoir à modifier les appelants est d'une grande valeur, tandis que la conception du logiciel est en train de changer.

Par conséquent, les deux types d'échanges sont très différentes.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X