2012-11-22 60 views
6

讓我開始說我不能在這裏放任何代碼,因爲我的筆記本電腦上的互聯網無法工作,所以我通過我的手機發布了這個消息。好的問題是說我有兩個班:一個班和兩個班。第一類具有ArrayList作爲其屬性之一,它從第二類中調用void方法,並將ArrayList作爲參數傳遞。現在該方法初始化另一個ArrayList並使其等於我傳遞的參數,並對該新的ArrayList進行更改。有趣的是,即使我作爲參數傳遞的原始ArrayList也在改變。可能的原因是什麼?傳遞ArrayList作爲參數

+0

我猜是因爲你有2個引用堆中的同一個對象。所以對第一個參考文獻的任何修改都會反映到另一個參考文獻中。有關更多詳細信息,請參閱http://stackoverflow.com/a/9404727/597657。 –

+0

列表是否更改(元素已刪除/添加/重新排序)或列表中的元素(它們的屬性)? – Andy

回答

5

問題是,當您使用=使新的ArrayList成爲原始副本時,您只需創建對同一個ArrayList的新引用。把它看作是指向同一個對象的兩個變量。

檢查了這一點,它可以幫助你瞭解發生了什麼:Is Java "pass-by-reference" or "pass-by-value"?

爲了解決你的問題,你需要使用「新」來創建一個新的ArrayList關鍵字,然後將所有的對象,或者使用clone()方法。

3

原因是當你傳遞一個ArrayList作爲參數時,被調用的方法可以改變數組的內容。 ArrayList包含對象的引用。 如果您想避免某些類將更改ArrayList的內容,您將擁有 以返回ArrayList的副本,其中所有內部對象都是列表中對象的clone()。

使用object.clone()

ArrayList clonedCopy = new ArrayList(list1.size()); 
for (Object obj : list1) { 
    clonedCopy.add(obj.clone()); 
} 

現在給這個clonedCopy回來。但要確保obj是可複製的!

+0

正確的點,但更簡單的代碼將是'ArrayList copy = new ArrayList(incomingList);' – user949300

+3

@ user949300不!你的代碼不會複製列表中的對象,它只會複製對它的引用。如果您的列表中有一個Date對象,並將其他類複製給另一個類。其他類可以更改您的列表中的Date對象!因此克隆,或者如果可能的話使用基本類型(日期:更長) – AlexWien

+0

真的,並且關於使用基元/不可變的好點。但是,這取決於是否允許其他班級進行更改。由於OP提到方法調用是無效的,他想要允許更改似乎是合理的。否則,目前還不清楚其他方法如何實際做任何事情。 – user949300

0

Java中的=運算符只會複製ArrayList引用(對於所有對象也是如此)。請參閱this answer以製作ArrayList的深層副本。

0

這是因爲當您使其等於時,新數組列表指向相同的舊數組。

這個小例子應該澄清它。

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

示例代碼:

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 
} 

} 

輸出:

[史蒂夫,丹尼爾,約翰,馬克西,傑尼]

[史蒂夫,丹尼爾·約翰,Maxi,Jeni,Pollard]