Tôi có một ArrayList<String>
cái mà tôi muốn trả lại một bản sao. ArrayList
có một phương pháp nhân bản có chữ ký sau:
public Object clone()
Sau khi tôi gọi phương thức này, làm cách nào để chuyển đối tượng được trả về ArrayList<String>
?
Tôi có một ArrayList<String>
cái mà tôi muốn trả lại một bản sao. ArrayList
có một phương pháp nhân bản có chữ ký sau:
public Object clone()
Sau khi tôi gọi phương thức này, làm cách nào để chuyển đối tượng được trả về ArrayList<String>
?
Câu trả lời:
ArrayList newArrayList = (ArrayList) oldArrayList.clone();
ArrayList<String> newArrayList = (ArrayList<String>) oldArrayList.clone();
.
List<String>
thay vì ArrayList<String>
ở phía bên trái. Đây là cách các bộ sưu tập nên được sử dụng hầu hết thời gian.
Tại sao bạn muốn sao chép? Tạo một danh sách mới thường có ý nghĩa hơn.
List<String> strs;
...
List<String> newStrs = new ArrayList<>(strs);
Công việc hoàn thành.
ArrayList(Collection<? extends E> c)
nghĩa là nó không quan trọng bạn sử dụng loại danh sách nào làm đối số.
Đây là mã tôi sử dụng cho điều đó:
ArrayList copy = new ArrayList (original.size());
Collections.copy(copy, original);
Hy vọng là hữu ích cho bạn
ArrayList
sử dụngArrayList<YourObject>
ArrayList
tạo?
Với Java 8, nó có thể được nhân bản với một luồng.
import static java.util.stream.Collectors.toList;
...
List<AnObject> clone = myList.stream().collect(toList());
toCollection
có thể là một lựa chọn tốt hơn
Xin lưu ý rằng Object.clone () có một số vấn đề lớn và việc sử dụng nó không được khuyến khích trong hầu hết các trường hợp. Vui lòng xem Mục 11, từ " Java hiệu quả " của Joshua Bloch để có câu trả lời đầy đủ. Tôi tin rằng bạn có thể sử dụng Object.clone () một cách an toàn trên các mảng kiểu nguyên thủy, nhưng ngoài ra, bạn cần thận trọng về việc sử dụng và ghi đè đúng cách. Bạn có lẽ tốt hơn hết là xác định một hàm tạo sao chép hoặc một phương thức tĩnh của nhà máy mà nhân bản rõ ràng đối tượng theo ngữ nghĩa của bạn.
Tôi nghĩ rằng điều này nên thực hiện thủ thuật bằng cách sử dụng API Bộ sưu tập:
Lưu ý : phương pháp sao chép chạy trong thời gian tuyến tính.
//assume oldList exists and has data in it.
List<String> newList = new ArrayList<String>();
Collections.copy(newList, oldList);
List<MySerializableObject> copyList = new ArrayList<>(mMySerializableObjects.size());
Có vẻ như sử dụng copyList.addAll(original);
là một thay thế tốt
int
cuộc tranh luận bí ẩn . Tôi không biết tại sao bạn muốn sử dụng phương pháp tĩnh tối nghĩa này thay vì cũ kỹaddAll
.
Tôi thấy việc sử dụng addAll hoạt động tốt.
ArrayList<String> copy = new ArrayList<String>();
copy.addAll(original);
dấu ngoặc đơn được sử dụng thay vì cú pháp tổng quát
new ArrayList<String>(original)
?
Nếu bạn muốn điều này để có thể trả về Danh sách trong một getter, tốt hơn là nên làm:
ImmutableList.copyOf(list);
Để sao chép một giao diện chung như java.util.List
bạn sẽ chỉ cần bỏ nó. đây là một ví dụ:
List list = new ArrayList();
List list2 = ((List) ( (ArrayList) list).clone());
Đó là một chút khó khăn, nhưng nó hoạt động, nếu bạn bị giới hạn trả lại một List
giao diện, vì vậy bất cứ ai sau khi bạn có thể thực hiện danh sách của bạn bất cứ khi nào anh ta muốn.
Tôi biết câu trả lời này gần với câu trả lời cuối cùng, nhưng câu trả lời của tôi trả lời làm thế nào để làm tất cả những điều đó trong khi bạn đang làm việc với List
- cha mẹ chung chung - không phảiArrayList
Hãy thật cẩn thận khi nhân bản ArrayLists. Nhân bản trong java là nông. Điều này có nghĩa là nó sẽ chỉ sao chép chính Arraylist chứ không phải các thành viên của nó. Vì vậy, nếu bạn có ArrayList X1 và sao chép nó vào X2, bất kỳ thay đổi nào trong X2 cũng sẽ xuất hiện trong X1 và ngược lại. Khi bạn sao chép, bạn sẽ chỉ tạo một ArrayList mới với các con trỏ tới cùng các phần tử trong bản gốc.
List<String> shallowClonedList = new ArrayList<>(listOfStrings);
Hãy nhớ rằng đây chỉ là một bản sao nông, không phải là một bản sao sâu, tức là. bạn nhận được một danh sách mới, nhưng các mục giống nhau. Đây không phải là vấn đề cho các chuỗi đơn giản. Khó khăn hơn khi các mục trong danh sách là chính các đối tượng.
Tôi không phải là một chuyên gia java, nhưng tôi có cùng một vấn đề và tôi đã cố gắng giải quyết bằng phương pháp này. (Giả sử T có một hàm tạo sao chép).
public static <T extends Object> List<T> clone(List<T> list) {
try {
List<T> c = list.getClass().newInstance();
for(T t: list) {
T copy = (T) t.getClass().getDeclaredConstructor(t.getclass()).newInstance(t);
c.add(copy);
}
return c;
} catch(Exception e) {
throw new RuntimeException("List cloning unsupported",e);
}
}
List
lớp triển khai có một hàm tạo không có đối số công khai. Chẳng hạn, List
s trả về bởi Array.asList
, List.of
hoặc List.subList
có thể không.