Java 8 cung cấp một cách mới để gọi hàm tạo sao chép hoặc phương thức sao chép trên các phần tử con chó một cách thanh lịch và gọn gàng: Luồng , lambdas và bộ thu .
Sao chép hàm tạo:
List<Dog> clonedDogs = dogs.stream().map(Dog::new).collect(toList());
Biểu thức Dog::newđược gọi là tham chiếu phương thức . Nó tạo ra một đối tượng hàm gọi hàm tạo trên Dogđó lấy một con chó khác làm đối số.
Phương pháp nhân bản [1]:
List<Dog> clonedDogs = dogs.stream().map(d -> d.clone()).collect(toList());
Lấy ArrayListkết quả
Hoặc, nếu bạn phải lấy ArrayListlại (trong trường hợp bạn muốn sửa đổi nó sau):
ArrayList<Dog> clonedDogs = dogs.stream().map(Dog::new).collect(toCollection(ArrayList::new));
Cập nhật danh sách tại chỗ
Nếu bạn không cần giữ nội dung gốc của dogsdanh sách, thay vào đó bạn có thể sử dụng replaceAllphương pháp và cập nhật danh sách tại chỗ:
dogs.replaceAll(Dog::new);
Tất cả các ví dụ giả định import static java.util.stream.Collectors.*;.
Người sưu tầm cho ArrayLists
Bộ sưu tập từ ví dụ cuối có thể được tạo thành một phương thức sử dụng. Vì đây là một điều phổ biến nên cá nhân tôi thích nó ngắn và đẹp. Như thế này:
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] Lưu ý về CloneNotSupportedException:
Để giải pháp này hoạt động, clonephương pháp Dog không được khai báo rằng nó ném CloneNotSupportedException. Lý do là đối số mapkhông được phép đưa ra bất kỳ ngoại lệ được kiểm tra nào.
Như thế này:
// Note: Method is public and returns Dog, not Object
@Override
public Dog clone() /* Note: No throws clause here */ { ...
Tuy nhiên, đây không phải là một vấn đề lớn, vì dù sao đó cũng là cách tốt nhất. ( Ví dụ về hiệu ứng Java đưa ra lời khuyên này.)
Cảm ơn Gustavo đã lưu ý điều này.
Tái bút
Thay vào đó, nếu bạn thấy nó đẹp hơn, bạn có thể sử dụng cú pháp tham chiếu phương thức để thực hiện chính xác điều tương tự:
List<Dog> clonedDogs = dogs.stream().map(Dog::clone).collect(toList());