Java 8 zapewnia nowy sposób wywoływania metody konstruktora kopiowania lub metody klonowania na psach elementu w elegancki i kompaktowy sposób: strumieni , lambd i kolektorów .
Kopiuj konstruktor:
List<Dog> clonedDogs = dogs.stream().map(Dog::new).collect(toList());
Wyrażenie Dog::new
to nazywa się odwołaniem do metody . Tworzy obiekt funkcyjny, który wywołuje konstruktor, Dog
który przyjmuje argument innego psa.
Metoda klonowania [1]:
List<Dog> clonedDogs = dogs.stream().map(d -> d.clone()).collect(toList());
Uzyskanie ArrayList
w wyniku
Lub, jeśli musisz uzyskać ArrayList
zwrot (na wypadek, gdybyś chciał go później zmodyfikować):
ArrayList<Dog> clonedDogs = dogs.stream().map(Dog::new).collect(toCollection(ArrayList::new));
Zaktualizuj listę na miejscu
Jeśli nie musisz zachowywać oryginalnej zawartości dogs
listy, możesz zamiast tego użyć replaceAll
metody i zaktualizować listę w miejscu:
dogs.replaceAll(Dog::new);
Wszystkie przykłady zakładają import static java.util.stream.Collectors.*;
.
Kolektor dla ArrayList
s
Kolektor z ostatniego przykładu można przekształcić w metodę util. Ponieważ jest to tak powszechna rzecz, osobiście podoba mi się, że jest krótka i ładna. Lubię to:
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] Uwaga CloneNotSupportedException
:
Aby to rozwiązanie zadziałało, clone
metoda Dog
nie może deklarować, że wyrzuca CloneNotSupportedException
. Powodem jest to, że argument do map
nie może generować sprawdzonych wyjątków.
Lubię to:
// Note: Method is public and returns Dog, not Object
@Override
public Dog clone() /* Note: No throws clause here */ { ...
Nie powinno to jednak stanowić dużego problemu, ponieważ i tak jest to najlepsza praktyka. ( Na przykład Java Java Effectice daje taką radę).
Dzięki Gustavo za zwrócenie uwagi na to.
PS:
Jeśli uważasz, że jest ładniejsza, możesz zamiast tego użyć składni odwołania do metody, aby zrobić dokładnie to samo:
List<Dog> clonedDogs = dogs.stream().map(Dog::clone).collect(toList());