2012-03-19 22 views
16

Giả sử chúng ta có một ArrayList myArray. Tôi muốn sửa đổi một đối tượng bằng cách gọi hàm của nó. Nếu tôi làm theo cách này, liệu đối tượng gốc sẽ được thay đổi hay không?ArrayList và sửa đổi các đối tượng được bao gồm trong nó

myArray.get(0).myModyfyingFunction(); 

Để làm rõ thêm - Tôi lo ngại nếu get() thực sự trả về tham chiếu đến đối tượng ban đầu của tôi hoặc chỉ trả về bản sao đối tượng gốc của tôi.

+7

Tại sao bạn không thử nó ra .. :) Đó là một vài dòng mã ... – PrimosK

+2

Kiểm tra bài viết này: http://www.javaranch.com /campfire/StoryPassBy.jsp (Toàn bộ con mèo điều khiển từ xa trong một khái niệm cốc là tuyệt vời) –

+0

Điểm tốt có @ PrimosK :) Tôi đoán tôi muốn nghe những lời giải thích cũng như tôi đã đọc rằng Java là pass-by- chỉ giá trị. –

Trả lời

51

get() sẽ trả về tham chiếu đến đối tượng, không bao giờ là bản sao. Bất kỳ sửa đổi nào bạn thực hiện đối với tham chiếu được trả lại sẽ được thực hiện trên đối tượng

+0

Cảm ơn bạn, tôi đã đọc rất nhiều blog, nơi nó nói rằng các đối tượng trong Java luôn được truyền theo giá trị và đó là lý do tại sao tôi bối rối. –

+3

Đó là sự thật, tất cả các đối tượng được truyền theo giá trị. Phần gây nhầm lẫn là _references_ cũng được truyền theo giá trị - nghĩa là khi bạn thêm đối tượng vào ArrayList, bạn kết thúc với hai tham chiếu trỏ đến cùng một đối tượng và nếu bạn sửa đổi một tham chiếu, "khác" cũng sẽ được sửa đổi , bởi vì cả hai đều trỏ đến cùng một đối tượng –

+0

@ PrimožKralj: "đối tượng" không phải là giá trị trong Java. Các đối tượng không bao giờ được truyền hoặc gán. Bạn đang gán và chuyển các tham chiếu, luôn luôn theo giá trị – newacct

1

Java không bao giờ trả về các bản sao của đối tượng, chỉ sao chép vào tham chiếu của đối tượng. Vì vậy, phương pháp chắc chắn sẽ thay đổi đối tượng tại chỉ số 0.

Bạn có thể nhận được một "bản sao" của một đối tượng nếu phương pháp sẽ tạo một đối tượng, ví dụ: bằng cách sử dụng return object.clone(); nếu có thể, nhưng thực sự là gì được trả lại là tham chiếu đến bản sao vẫn được tạo trong phương thức. Vì vậy, bạn có thể nhận được một "bản sao" của một đối tượng trong một ý nghĩa rộng hơn, nhưng ArrayList#get(...) sẽ không làm điều đó - và theo quy ước, không getter nên làm điều đó trừ khi được tuyên bố rõ ràng.

+0

Cảm ơn bạn, sự hiểu biết của tôi bây giờ tốt hơn;) –

1

Điều này phụ thuộc vào loại đối tượng bạn đã lưu trữ trong ArrayList của mình. Ví dụ, nếu chúng là java.lang.String s, các cuộc gọi sẽ không sửa đổi bất cứ điều gì. Nếu không, có, nó sẽ sửa đổi đối tượng của bạn được lưu trữ tại chỉ mục 0.

+0

Điểm tốt về việc thực hiện phương pháp, nhưng tôi nghĩ trong trường hợp này chúng ta có thể giả định nó sẽ thực sự sửa đổi cá thể nó được gọi trên. :) – Thomas

+0

Cảm ơn bạn, tốt để biết điều này về chuỗi. –

+0

nó không phụ thuộc vào loại đối tượng của nó. Nó chỉ phụ thuộc vào phương pháp. Chuỗi chỉ xảy ra để không có bất kỳ phương thức nào làm biến đổi nó – newacct

1

Nó cung cấp cho bạn tham chiếu đến đối tượng, nếu chức năng của bạn thực hiện bất kỳ sửa đổi nào trong trạng thái của nó, đối tượng của bạn sẽ được sửa đổi.

Cùng xảy ra khi bạn làm điều này:

ArrayList myArray = new ArrayList(); 
MyObject obj = new MyObject(); 
myArray.add(obj); 
obj.myModifyingFunction(); 
myArray.get(0).equals(obj); // returns true 
myArray.get(0) == obj; // returns true as well 
+0

'myArray.get (0) .equals (obj);' thực sự có thể trả về true nếu 'obj' không phải là cùng một thể hiện nhưng chỉ bằng nhau về mặt logic (phụ thuộc vào việc thực thi' bằng() '). – Thomas

+0

quan sát tốt, tôi sửa đổi câu trả lời của tôi để làm rõ rằng đối tượng đã được sửa đổi và nó là cùng một tài liệu tham khảo mà thêm một (và nó cũng hợp lý bằng nhau). –

+0

Cảm ơn bạn đã giải thích và cung cấp ví dụ. –

7

Nếu bạn lưu trữ bất kỳ đối tượng trong ArrayList, Object không lặp lại và bất kỳ thay đổi trong đối tượng cần phản ánh trong bản thân đối tượng.

ví dụ chúng tôi có lớp NewClass

public class NewClass { 

private String mystring=""; 

/** 
* @return the mystring 
*/ 
public String getMystring() { 
    return mystring; 
} 

/** 
* @param mystring the mystring to set 
*/ 
public void setMystring(String mystring) { 
    this.mystring = mystring; 
} 

}

đây là mã trong phương pháp chính của bất kỳ lớp khác

List<NewClass> newclasses = new ArrayList<NewClass>(); 
    NewClass class1 = new NewClass(); 
    class1.setMystring("before1"); 
    NewClass class2 = new NewClass(); 
    class2.setMystring("before2"); 
    newclasses.add(class1); 
newclasses.add(class2); 
newclasses.get(0).setMystring("after1"); 
System.out.println(class1.getMystring()); 

chí đầu ra này after1.

0
Here is an barebone example. Modify an object of Test class in the List. 

    public class ModifyArrayList{ 


    public static void main(String [] args){  
      List<Test> l = new ArrayList<Test>(); 
    Test t1 = gettest(); 
    t1.setStr("John"); 
    t1.setInte(100); 
    t1.setAno("Smith"); 
    l.add(t1); 
    t1 = new Test(); 
    t1.setStr("Tracy"); 
    t1.setInte(100); 
    t1.setAno("Pinto"); 
    l.add(t1); 
    t1 = new Test(); 
    t1.setStr("Ryan"); 
    t1.setInte(100); 
    t1.setAno("SmithPinto"); 
    l.add(t1); 
    t1 = new Test(); 
    t1.setStr("Someone"); 
    t1.setInte(100); 
    t1.setAno("Else"); 
    l.add(t1); 



    ListIterator<Test> ti = l.listIterator(); 

    while(ti.hasNext()) 
    { 
     Test t = ti.next(); 
     if(t.getAno().equals("SmithPinto")) 
     { 
      t.setInte(200); 
         } 
     //ti.set(t); 
     ti.remove(); 
     ti.add(t); 
    } 
      for (Test t:l) 
    { 
     System.out.println("TEST: " + t.getInte()); 
    } 
      } 
    } 


    //Test Class below: 

    public class Test { 

    private String str; 
    private int inte; 
     public String getStr() { 
    return str; 
     } 
       public void setStr(String str) { 
        this.str = str; 
            } 
public int getInte() { 
    return inte; 
} 
public void setInte(int inte) { 
    this.inte = inte; 
} 
public String getAno() { 
    return ano; 
} 
public void setAno(String ano) { 
    this.ano = ano; 
} 
private String ano; 

}

0
for(User user: Users){ 

user.setName(user.getName() + " New Name"); 

} 

for(User user: Users){ 

System.out.println(user.getName()); 

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