2012-11-22 41 views
6

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ố

+0

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. –

+0

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

Trả lời

5

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().

1

Vì chúng trỏ đến cùng một tham chiếu.

3

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!

+0

Đ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

+3

@ 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

+0

Đú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

0

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.

0

Đ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"); 
    } 
} 
1

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]

Các vấn đề liên quan