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::newest appelée référence de méthode . Il crée un objet fonction qui appelle un constructeur sur Doglequel prend un autre chien comme argument.
Méthode de clonage [1]:
List<Dog> clonedDogs = dogs.stream().map(d -> d.clone()).collect(toList());
Obtenir un ArrayListrésultat
Ou, si vous devez obtenir un ArrayListretour (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 dogsliste, vous pouvez plutôt utiliser la replaceAllméthode et mettre à jour la liste en place:
dogs.replaceAll(Dog::new);
Tous les exemples supposent import static java.util.stream.Collectors.*;.
Collectionneur pour ArrayLists
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 cloneméthode de Dog ne doit pas déclarer qu'elle lance CloneNotSupportedException. La raison en est que l'argument to mapn'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());