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 ArrayList
kết quả
Hoặc, nếu bạn phải lấy ArrayList
lạ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 dogs
danh sách, thay vào đó bạn có thể sử dụng replaceAll
phươ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 ArrayList
s
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, clone
phương pháp Dog
không được khai báo rằng nó ném CloneNotSupportedException
. Lý do là đối số map
khô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());