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 ArrayListgeri 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
dogsListenin orijinal içeriğini korumanız gerekmiyorsa , replaceAllyö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ı ArrayListS
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 cloneyö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());