Java 8 fournit une nouvelle façon d'appeler le constructeur de copie ou la méthode de clonage sur les chiens d'élément de manière élégante et compacte: Streams , lambdas et collectors .
Constructeur de copie:
List<Dog> clonedDogs = dogs.stream().map(Dog::new).collect(toList());
L'expression Dog::new
est appelée référence de méthode . Il crée un objet fonction qui appelle un constructeur sur Dog
lequel prend un autre chien comme argument.
Méthode de clonage [1]:
List<Dog> clonedDogs = dogs.stream().map(d -> d.clone()).collect(toList());
Obtenir un ArrayList
résultat
Ou, si vous devez obtenir un ArrayList
retour (au cas où vous voudriez le modifier plus tard):
ArrayList<Dog> clonedDogs = dogs.stream().map(Dog::new).collect(toCollection(ArrayList::new));
Mettre à jour la liste en place
Si vous n'avez pas besoin de conserver le contenu d'origine de la dogs
liste, vous pouvez plutôt utiliser la replaceAll
méthode et mettre à jour la liste en place:
dogs.replaceAll(Dog::new);
Tous les exemples supposent import static java.util.stream.Collectors.*;
.
Collectionneur pour ArrayList
s
Le collecteur du dernier exemple peut être transformé en une méthode util. Comme c'est une chose courante à faire, j'aime personnellement que ce soit court et joli. Comme ça:
ArrayList<Dog> clonedDogs = dogs.stream().map(d -> d.clone()).collect(toArrayList());
public static <T> Collector<T, ?, ArrayList<T>> toArrayList() {
return Collectors.toCollection(ArrayList::new);
}
[1] Remarque sur CloneNotSupportedException
:
Pour que cette solution fonctionne, la clone
méthode de Dog
ne doit pas déclarer qu'elle lance CloneNotSupportedException
. La raison en est que l'argument to map
n'est pas autorisé à lever des exceptions vérifiées.
Comme ça:
// Note: Method is public and returns Dog, not Object
@Override
public Dog clone() /* Note: No throws clause here */ { ...
Cela ne devrait cependant pas être un gros problème, car c'est de toute façon la meilleure pratique. ( Effectice Java par exemple donne ce conseil.)
Merci à Gustavo de l'avoir noté.
PS:
Si vous le trouvez plus joli, vous pouvez utiliser la syntaxe de référence de la méthode pour faire exactement la même chose:
List<Dog> clonedDogs = dogs.stream().map(Dog::clone).collect(toList());