Java 8, eleman köpeklerindeki kopya yapıcı veya klon yöntemini zarif ve kompakt bir şekilde çağırmak için yeni bir yol sağlar: Akımlar , lambdalar ve toplayıcılar .
Kopya oluşturucu:
List<Dog> clonedDogs = dogs.stream().map(Dog::new).collect(toList());
İfadeye yöntem başvurusuDog::new
denir . Başka bir köpeği argüman olarak alan bir kurucuyu çağıran bir fonksiyon nesnesi oluşturur .Dog
Klonlama yöntemi [1]:
List<Dog> clonedDogs = dogs.stream().map(d -> d.clone()).collect(toList());
Bir ArrayList
sonucunda
Veya, bir ArrayList
geri almanız gerekiyorsa (daha sonra değiştirmek isterseniz):
ArrayList<Dog> clonedDogs = dogs.stream().map(Dog::new).collect(toCollection(ArrayList::new));
Listeyi yerinde güncelleyin
dogs
Listenin orijinal içeriğini korumanız gerekmiyorsa , replaceAll
yöntemi kullanabilir ve listeyi yerinde güncelleyebilirsiniz:
dogs.replaceAll(Dog::new);
Tüm örnekler varsayılmaktadır import static java.util.stream.Collectors.*;
.
İçin toplayıcı ArrayList
S
Son örnekten toplayıcı bir util yöntemine dönüştürülebilir. Bu çok yaygın bir şey olduğu için kişisel olarak kısa ve güzel olmasını seviyorum. Bunun gibi:
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] Not CloneNotSupportedException
:
Bu çözümün işe yaraması için clone
yönteminin atıldığını beyan Dog
etmemelidirCloneNotSupportedException
. Bunun nedeni,map
kontrol edilen istisnaları atmasına izin verilmemesidir.
Bunun gibi:
// Note: Method is public and returns Dog, not Object
@Override
public Dog clone() /* Note: No throws clause here */ { ...
Bununla birlikte, bu büyük bir sorun olmamalı, çünkü bu zaten en iyi uygulamadır. ( Örneğin, Effectice Java bu tavsiyeyi verir.)
Gustavo'ya bunu kaydettiği için teşekkürler.
Not:
Daha güzel bulursanız, aynı şeyi yapmak için yöntem referans sözdizimini kullanabilirsiniz:
List<Dog> clonedDogs = dogs.stream().map(Dog::clone).collect(toList());