2012-11-17 91 views
2

我有一個ArrayList包含對象。 (這些對象是分類,每個對象都包含大量的信息,這些對象恰恰代表了大型發電機,因此不能一個一個地複製這些屬性)。Clonning ArrayList元素到相同的ArrayList

例如:

ArrayList arr = {ob1, ob2, ob3, ob4, ob5} 

所以我嘗試做的是克隆的對象(OB1)的位置5

arr.set(4, arr.get(0)); 

但不知何故,這樣做,OB5不是副本ob ob1,它是ob1,所以如果我改變ob5,ob1也會改變。

這是ArrayLists固有的東西嗎? 如果我使用列表,是否有任何區別?

回答

1

這是因爲您正在執行影子副本而不是深層副本。

淺拷貝:如果在Obj-1上執行淺拷貝,那麼它將被複制,但其包含的對象不是。包含的對象Obj-1Obj-2受更改克隆Obj-2影響。當類實現java.lang.Cloneable接口時,Java默認支持對象的淺層克隆。

深層複製:如果如圖所示,然後深拷貝是在obj-1執行不僅obj- 1已經被複制,但它所包含的對象已經被複制以及。序列化可用於實現深度克隆。通過序列化進行深度克隆的開發速度更快,更容易維護,但會帶來性能開銷。 source

深複製的一個例子:

class Student implements Cloneable { 
    //Contained object 
    private Subject subj; 
    private String name; 

    public Subject getSubj() {..} 
    public String getName() {..} 

    public Object clone() { 
    //Deep copy 
    Student s = new Student(name, subj.getName()); 
    return s; 
    } 
} 
0

這將是真正的在Java中的任何地方。 沒有將得到複製,除非你明確這樣做。 (的確,有些對象故意不可複製。)

0

您需要複製ElectricGenerator。最常見的選項是引入複製構造函數或實現克隆方法。但是這兩種解決方案都需要複製所有這些屬性。

一旦你有,你可以做

//copy constructor 
arr.add(new ElectricGenerator(arr.get(0))); 
//clone 
arr.add(arr.get(0).clone()); 

另一種方法是序列化/反序列化對象

0

這不是附着於ArrayList中,這是一個Java功能。新對象不會創建,只會傳遞一個引用。 ArrayList因此存儲兩個引用。你必須使用你的對象的.clone()方法。

arr.set(4, arr.get(0).clone()); 

這將創建該對象的新副本,即使此副本很淺。如果需要,您必須重寫克隆方法以使其成爲深層副本。

0

沒有那是因爲在Java中創建的對象的引用,所以即使你不使用ArrayList和做這樣的事情:

String a = new String("a"); 
String b = a; 

b += "b"; 

a和b是相等的「AB」。

(從這個例外是像int這樣的基本類型(但不是Integer的實例有不同的東西))。

所以回答你的問題就在這裏: How to copy an object by value, not by reference 這裏: http://www.itcsolutions.eu/2010/12/29/tutorial-java-6-4-2-how-to-copy-values-of-an-array-into-another-array/

0

名單隻包含指向一個對象..

如果將OB1到OB5會發生什麼它告訴列表將指針指向ob1的指針所在的ob1,因此丟失指向ob5的指針並複製ob1的指針...

您需要創建另一個對象包含值的重複,然後將該對象分配給位置4

0

對象變量與基本數據類型不同。

int x = 2; 
int y = x; 

x和y指的是不同的內存位置。

MyClass x = new MyClass(); 
MyClass y = x; 

x和y指的是相同的內存位置,但該位置有兩個引用。對一個人做的任何改變都會改變另一個人。在解決這個問題的方法是實施Cloneable並使用.clone()方法。

0

shallow copying創建相同類的新實例並將所有字段複製到新實例並將其返回。對象類提供了一種克隆方法,併爲淺拷貝提供支持。

2

ArrayList保存引用yes。但是你可以克隆它(注意,但它將是淺拷貝 - 它不會複製以及內部對象https://stackoverflow.com/a/13434779/1111527

private class JustToCheck implements Cloneable { 

    @Override 
    public Object clone() throws CloneNotSupportedException { 
     return super.clone(); 
    } 
} 

然後用這樣

JustToCheck ob1 = new JustToCheck(); 
JustToCheck ob2 = ob1; 

List<JustToCheck> arr = new ArrayList<JustToCheck>(); 
arr.add(ob1); 
arr.add(ob2); 

System.out.println(arr.get(0).toString() + ": " + arr.get(1).toString()); 

try { 
    arr.set(1, (JustToCheck) ob1.clone()); 
} catch (CloneNotSupportedException e) { 
    e.printStackTrace(); 
} 

System.out.println(arr.get(0).toString() + ": " + arr.get(1).toString()); 

輸出被

[email protected]: [email protected] 
[email protected]: [email protected] 


PS - 我已經檢查了問題的答案https://stackoverflow.com/a/13434813/1111527

有什麼用一成不變的類

的Java6

String a = new String("a"); 
String b = a; 
b += "b"; 
System.out.println("a = " + a); // a = a 
System.out.println("b = " + b); // b = ab