Hãy để tôi bắt đầu bằng cách nói rằng tôi không thể đặt bất kỳ mã nào ở đây vì Internet trên máy tính xách tay của tôi không hoạt động nên tôi đăng bài này qua điện thoại của mình. Được rồi vấn đề là nói rằng tôi có hai lớp: lớp một và hai. Lớp một có một số ArrayList
là một trong các thuộc tính của nó và nó gọi một phương thức void từ lớp hai và vượt qua ArrayList
làm tham số. Bây giờ phương thức đó khởi tạo một số ArrayList
khác và làm cho nó bằng tham số được truyền bởi tôi và thực hiện các thay đổi cho ArrayList
mới đó. Điều thú vị là ngay cả ArrayList ban đầu của tôi đã được thông qua như tham số cũng đang thay đổi. Điều gì có thể là lý do có thể?Truyền ArrayList làm tham số
Trả lời
Vấn đề là khi bạn sử dụng = để tạo ArrayList mới một bản sao của bản gốc, bạn chỉ cần tạo một tham chiếu mới cho cùng một ArrayList. Hãy suy nghĩ về nó như là hai biến chỉ vào cùng một đối tượng.
Kiểm tra này ra, nó có thể giúp bạn hiểu những gì đang xảy ra: Is Java "pass-by-reference" or "pass-by-value"?
Để giải quyết vấn đề của bạn, bạn cần phải tạo một ArrayList mới bằng cách sử dụng "mới" từ khoá và sau đó thêm tất cả các đối tượng, hoặc sử dụng phương thức clone().
Vì chúng trỏ đến cùng một tham chiếu.
Lý do là khi bạn chuyển đối số ArrayList làm đối số, phương thức được gọi có thể thay đổi nội dung của mảng. ArrayList chứa các tham chiếu đến các đối tượng. Nếu bạn muốn tránh rằng một số lớp sẽ thay đổi nội dung của ArrayList của bạn, bạn có để trả về Sao chép ArrayList của bạn, nơi tất cả các đối tượng bên trong là bản sao() của các đối tượng trong danh sách của bạn.
Sử dụng Object.clone()
ArrayList clonedCopy = new ArrayList(list1.size());
for (Object obj : list1) {
clonedCopy.add(obj.clone());
}
Bây giờ cho clonedCopy này trở lại. Nhưng hãy chắc chắn obj là cloneable!
Điểm chính xác, nhưng mã đơn giản hơn sẽ là 'ArrayList copy = new ArrayList (danh sách gửi đến);' – user949300
@ user949300 NO! mã của bạn sẽ không sao chép các đối tượng bên trong danh sách, nó sẽ chỉ sao chép một tham chiếu đến nó. Nếu bạn có một đối tượng Date bên trong danh sách của bạn, và cung cấp cho yur copyied list đến một lớp khác. rằng lớp khác có thể thay đổi đối tượng Ngày của bạn trong danh sách của bạn! Vì vậy, sao chép, hoặc sử dụng các kiểu nguyên thủy nếu có thể (Ngày: tốt hơn dài) – AlexWien
Đúng, và tốt về việc sử dụng nguyên thủy/bất biến. Nhưng, nó phụ thuộc nếu bạn muốn cho phép lớp khác thay đổi hay không. Vì OP đã đề cập rằng cuộc gọi phương thức là một khoảng trống, có vẻ như anh ta muốn cho phép thay đổi. Nếu không thì không rõ phương pháp kia thực sự sẽ làm gì. – user949300
Toán tử =
trong Java sẽ chỉ sao chép tham chiếu ArrayList
(giống với tất cả các đối tượng). Xem this answer để tạo bản sao sâu của một ArrayList.
Điều này là do danh sách mảng mới trỏ đến cùng một mảng cũ khi bạn làm cho nó bằng.
Ví dụ nhỏ này nên làm rõ.
import java.util.ArrayList;
import java.util.List;
public class JavaApplication1 {
public static void main(String[] args) {
List <String> origList = new ArrayList<>();
origList.add("a");
origList.add("b");
JavaApplication1 app = new JavaApplication1();
app.addToList(origList);
for(String str:origList){
System.out.println(str);
}
}
private void addToList(List<String> strList){
System.out.println("inside addToList");
List <String> newList = new ArrayList<>();
// newList = strList; //This is how you are doing it
newList.addAll(strList); //This is how you should do it.
newList.add("x");
}
}
Sample Code:
public class MethodArguments {
public static void main(String args[]) {
ArrayList<String> a = new ArrayList<String>();
a.add("Steve");
a.add("Daniel");
a.add("John");
a.add("Maxi");
a.add("Jeni");
System.out.println(a);
display(a);
getSize(a);
}
static void display(ArrayList<String> arrayList1) {
arrayList1.add("Pollard");
System.out.println(arrayList1); // passing the arraylist values and
// adding the element
}
static void getSize(ArrayList<String> arrayList1) {
System.out.println(arrayList1.size()); // getting the size of arraylist
// by passing arguments to
// method
}
}
Output:
[Steve, Daniel, John, Maxi, Jeni]
[Steve, Daniel, John , Maxi, Jeni, Pollard]
- 1. Chỉ truyền ArrayList làm giá trị và không tham chiếu
- 2. Truyền tham số trong Link_to
- 3. Tham số truyền bằng initWithNibName:
- 4. Truyền tham số qua server.execute?
- 5. Truyền tham số cho BroadcastReceiver
- 6. Truyền Lớp như tham số
- 7. Truyền tham số cho tác vụ vải
- 8. Truyền tham số cho đối tượng XMLHttpRequest
- 9. tham số truyền vào php với shell
- 10. Truyền tham số cho MVC Ajax.ActionLink
- 11. Truyền tham số trong đường ray redirect_to
- 12. Truyền tham số cho System.EventHandler bằng C#
- 13. Python: Truyền tham số theo tên
- 14. Làm thế nào để truyền tham số cho một ServiceHost
- 15. Truyền đại biểu làm tham số phương thức
- 16. Phương thức truyền dẫn mục tiêu-C làm tham số
- 17. Truyền phương thức của Giao diện làm tham số
- 18. Các generics Java truyền tham số
- 19. bản sao của hàm tạo với tham số ArrayList
- 20. Truyền tham số trong hàm setInterval
- 21. Android: truyền tham số cho một tab
- 22. Biết số tham số của hàm được truyền (erlang)
- 23. Python: chuyển hàm có tham số làm tham số
- 24. Hibernate -> ArrayList không thể được truyền tới Set
- 25. Làm thế nào để truyền số nguyên như tham số unsigned trong VB.NET?
- 26. Truyền tham số sang chế độ xem erb
- 27. Truyền tham số cho các hàm bản đồ trong CouchDb
- 28. Truyền mảng tham số so với tham số riêng lẻ cho một hàm trong PHP?
- 29. JavaScript: Truyền tham số đến hàm gọi lại
- 30. Tham số gsp truyền từ bộ điều khiển
Tôi đoán vì bạn có 2 tham chiếu đến cùng một đối tượng trong vùng. Vì vậy, bất kỳ sửa đổi nào về tham chiếu đầu tiên sẽ được phản ánh cho tham chiếu khác. Xem http://stackoverflow.com/a/9404727/597657 để biết thêm chi tiết. –
Thay đổi danh sách (các phần tử bị xóa/thêm/sắp xếp lại) hay các phần tử trong danh sách (thuộc tính của chúng)? – Andy