java: de retour d'une collection
Quelle est la meilleure façon de renvoyer une collection en Java?
Dois-je permettre à l'appelant de fournir une collection à ajouter? Ou juste de retour d'un List<>
ou Set<>
des articles? Ou les deux?
public class Item { ... }
public class SomeOtherClass
{
private List<Item> myItems;
public List<Item> getItems()
{
return Collections.unmodifiableList(this.myItems);
}
public void collectItems(Collection<? super Item> target)
{
target.addAll(myItems);
}
}
remarque: l'exemple ci-dessus suppose l'existence préalable d'une liste qui peut être immédiatement retournés. Je suis également intéressé par la réponse appropriée lorsqu'une telle liste n'est pas le cas auparavant et doit être généré lorsque l'appelant appels getItems() ou collectItems().
(J'ai renommé collectItems basée sur le point soulevé par Mykola.)
- +1 pour la présentation des Collections.unmodifiableList. Juste ce que je cherchais.
Vous devez vous connecter pour publier un commentaire.
J'avais juste préfèrent les
List<Item> getItems()
méthode. Il n'y a pas de réel avantage àvoid getItems(Collection<? super Item> target)
plus de l'appelant juste fairemyCollection.addAll(foo.getItems())
de performance ou autre.Collections.unmodifiableXYZ
seulement crée un wrapper, pas une copie complète de la collection, donc si le wrapper est immédiatement utilisé et jeté, il ne sera jamais sortir de la première génération et seront recueillies rapidement, à peu de frais généraux.Si la collecte des éléments n'est pas toujours réalisé, vous pourriez envisager d'avoir getItems retour
Iterable<Item>
lorsque vous ne savez pas combien d'objets il y a des. Si vous connaissez le nombre d'éléments et peut écrire un itérateur pour eux, alors il est facile d'écrire une sous-classe personnalisée deAbstractCollection
et de retour que.C'est mieux (à moins que certains problèmes de performances) pour retourner le résultat dans une des fonctions via
return
. De cette façon, il est plus clair de ce qui se passe.Si vous choisissez la deuxième option (remplissage du client de la collection) qu'il serait préférable de renommer la fonction de
getItems
à quelque chose commefillWithItems
pour éviter ambigu code.Aussi, ne pas oublier de JavaBeans et sa convention.
Vous devez retourner un de la collection. C'est une approche plus commune dans Java que pour l'usage dans/paramètres de sortie. Je ne vois pas pourquoi il y aurait une perte de performance pour le retour d'une grande collection, et il sera beaucoup plus propre code.
Compte tenu de la façon dont Java œuvres vous attendent le retour de la version.
Toutefois, si vous avez besoin de contrôle sur ce type de collection est créée alors vous feriez la version où vous le passer comme un argument.
Généralement rien de les soins de ce type de collection est créée, de sorte que vous devriez aller avec le retour de la version. Bonne utilisation de la unmodifiableList par la voie.
Note: de Retour d'un Jeu et de retourner une Liste ont des implications différentes.
Un Jeu n'a pas de doublons et aucun ordre indiqué. L'ajout d'un élément à un ensemble peut changer l'ordre des éléments.
Une Liste peut contenir des doublons et l'ajout d'un élément à ne pas (généralement) de modifier l'ordre de la liste.
Que pour la façon dont vous retourner la liste, je voudrais utiliser la première forme:
Je ne peux pas imaginer une situation où cette dernière forme serait d'aucun avantage. Une Liste n'est pas comme un tableau où l'espace peut être pré-alloués. Donc, il n'y a pas de rendement de l'épargne en passant dans une Liste.
La seule raison pour laquelle je peux penser à remplir une collection existante plutôt que d'en faire un nouveau, c'est quand vous avez des problèmes avec le type de l'objet dans la collection. Comme la bibliothèque Java toArray(Object[] a) la fonction, où le programme ne connaît pas au moment de la compilation que le type des éléments du tableau seront, donc il ne peut pas revenir, par exemple, une Chaîne de caractères[]. Alors, ils ont l'appelant passer un tableau avec le type d'éléments, et ils se remplissent que.
90% du temps, vous savez exactement quels sont les types d'objets que vous voulez retourner, alors vous pouvez le faire.
Vous pourriez modifier votre signature à renvoyer une Collection ou Itératif. Pour le retour Itérable, vous pouvez renvoyer une nouvelle chose-Itérable(myItems.iterator()) au lieu de myItems directement pour éviter que le client peut-être essayer de jeter une Liste (et de modifier). Si vous ne voulez pas modifier la Liste, également envisager de revenir un Itérateur aussi, mais note que Itérable est mieux car vous pouvez l'utiliser directement les personnes dans les boucles for-each.
De retourner un objet iterable fait part de votre intention et claire dans l'exemple ci-dessus, empêche toute modification. La seule conséquence est que vous avez perdu l'accès aléatoire, qui peut ou peut ne pas être un problème pour vos besoins.
new Iterable(myItems.iterator())
n'est pas légal; avez-vous dire autre chose?