Java 8 menyediakan cara baru untuk memanggil metode copy constructor atau clone pada elemen dogs secara elegan dan kompak: Streaming , lambdas dan kolektor .
Salin konstruktor:
List<Dog> clonedDogs = dogs.stream().map(Dog::new).collect(toList());
Ungkapan Dog::new
ini disebut referensi metode . Ini menciptakan objek fungsi yang memanggil konstruktor Dog
yang mengambil anjing lain sebagai argumen.
Metode klon [1]:
List<Dog> clonedDogs = dogs.stream().map(d -> d.clone()).collect(toList());
Mendapatkan ArrayList
sebagai hasilnya
Atau, jika Anda harus mendapatkan ArrayList
kembali (jika Anda ingin mengubahnya nanti):
ArrayList<Dog> clonedDogs = dogs.stream().map(Dog::new).collect(toCollection(ArrayList::new));
Perbarui daftar di tempat
Jika Anda tidak perlu menyimpan konten asli dari dogs
daftar Anda bisa menggunakan replaceAll
metode ini dan memperbarui daftar di tempat:
dogs.replaceAll(Dog::new);
Semua contoh mengasumsikan import static java.util.stream.Collectors.*;
.
Kolektor untuk ArrayList
s
Kolektor dari contoh terakhir dapat dibuat menjadi metode util. Karena ini adalah hal yang biasa dilakukan, saya pribadi suka itu pendek dan cantik. Seperti ini:
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] Catatan tentang CloneNotSupportedException
:
Agar solusi ini berfungsi, clone
metode Dog
harus tidak menyatakan bahwa ia melempar CloneNotSupportedException
. Alasannya adalah bahwa argumen untuk map
tidak diizinkan untuk membuang pengecualian yang diperiksa.
Seperti ini:
// Note: Method is public and returns Dog, not Object
@Override
public Dog clone() /* Note: No throws clause here */ { ...
Namun ini seharusnya tidak menjadi masalah besar, karena itu adalah praktik terbaik. ( Effectice Java misalnya memberikan saran ini.)
Terima kasih kepada Gustavo karena memperhatikan ini.
PS:
Jika Anda merasa lebih cantik, Anda dapat menggunakan sintaks referensi metode untuk melakukan hal yang persis sama:
List<Dog> clonedDogs = dogs.stream().map(Dog::clone).collect(toList());