[英]Java - Implement deep and shallow copy of an array
我試圖理解Java中淺層和深層復制的概念。 關於這個主題有很多文章和問答,但每當我嘗試在真正的Java代碼中實現這些概念時,我都不清楚一切。
我基於理解的答案之一就是在這個鏈接中 ,通過模式解釋深度和淺層復制。
我會在每個案例的實施情況下向您展示:
我在我的示例中使用了System.arraycopy()方法,因為我在許多文章中讀到它執行淺拷貝(以及克隆方法)
public class Test {
public static void main(String[] args) {
NameValue[] instance1 = {
new NameValue("name1", 1),
new NameValue("name2", 2),
new NameValue("name3", 3),
};
NameValue[] instance2 = new NameValue[instance1.length];
// Print initial state
System.out.println("Arrays before shallow copy:");
System.out.println("Instance 1: " + Arrays.toString(instance1));
System.out.println("Instance 2: " + Arrays.toString(instance2));
// Perform shallow copy
System.arraycopy(instance1, 0, instance2, 0, 3);
// Change instance 1
for (int i = 0; i < 3; i++) {
instance1[i].change();
}
// Print final state
System.out.println("Arrays after shallow copy:");
System.out.println("Instance 1: " + Arrays.toString(instance1));
System.out.println("Instance 2: " + Arrays.toString(instance2));
}
private static class NameValue {
private String name;
private int value;
public NameValue(String name, int value) {
super();
this.name = name;
this.value = value;
}
public void change() {
this.name = this.name + "-bis";
this.value = this.value + 1;
}
@Override
public String toString() {
return this.name + ": " + this.value;
}
}
}
執行主要方法的結果如下:
Arrays before shallow copy:
Instance 1: [name1: 1, name2: 2, name3: 3]
Instance 2: [null, null, null]
Arrays after shallow copy:
Instance 1: [name1-bis: 2, name2-bis: 3, name3-bis: 4]
Instance 2: [name1-bis: 2, name2-bis: 3, name3-bis: 4]
我在這個例子中使用了Arrays.copyOf()方法,因為我在許多文章中讀到它執行深層復制(以及Arrays.copyOfRange方法)
public static void main(String[] args) {
NameValue[] instance1 = {
new NameValue("name1", 1),
new NameValue("name2", 2),
new NameValue("name3", 3),
};
NameValue[] instance2 = new NameValue[instance1.length];
// Print initial state
System.out.println("Arrays before deep copy:");
System.out.println("Instance 1: " + Arrays.toString(instance1));
System.out.println("Instance 2: " + Arrays.toString(instance2));
// Perform deep copy
instance2 = Arrays.copyOf(instance1, 3);
// Change instance 1
for (int i = 0; i < 3; i++) {
instance2[i].change();
}
// Print final state
System.out.println("Arrays after deep copy:");
System.out.println("Instance 1: " + Arrays.toString(instance1));
System.out.println("Instance 2: " + Arrays.toString(instance2));
}
顯示:
Arrays before deep copy:
Instance 1: [name1: 1, name2: 2, name3: 3]
Instance 2: [null, null, null]
Arrays after deep copy:
Instance 1: [name1-bis: 2, name2-bis: 3, name3-bis: 4]
Instance 2: [name1-bis: 2, name2-bis: 3, name3-bis: 4]
您可能會注意到,main方法的執行結果與上面的模式邏輯不同。
任何解釋都將受到歡迎。
我不知道你在哪里讀到copyOf()
執行深層復制,因為這是完全錯誤的。
引用Arrays.copyOf(T[] original, int newLength)
javadoc:
對於在原始數組和副本中都有效的所有索引, 這兩個數組將包含相同的值 。
這意味着它是一個淺薄的副本。 要成為深層副本,值必須指向不同的對象,因為引用的對象也必須是副本。
要執行深層復制, 您必須迭代數組並復制值。 Java無法為您做到這一點,因為它不知道如何復制對象。
例如,Java如何知道如何復制NameValue
對象? clone()
? 復制構造函數? 序列化+反序列化? 工廠方法? 其他方法?
我試圖理解Java中淺層和深層復制的概念。
在Java中,您傳遞並存儲對象的引用而不是對象本身。
因此,當您擁有NameValue[] array
該數組不包含對象NameValue
而是對對象的引用。
因此,當您對NameValue[] array2
執行淺復制時,這意味着您只是將引用從一個數組復制到另一個數組。 這實際上意味着現在array
和array2
指向完全相同的對象,並且從array2[2]
(同一個對象)可以看到從array[2]
進行的任何更改。
深度復制時,將每個對象完全復制到另一個內存區域,並在新陣列中保留對該新對象的引用。
這樣,2個數組現在引用不同的對象,並且從array2[2]
看不到對array[2]
任何更改
更新:
這不適用於存儲實際值而不是引用的基元。
所以當你復制時你得到一個int[] a
得到一個值的副本(即某種意義上的深拷貝),因為a[2]
包含值本身而不是對值的引用。
我認為有一點誤解, Arrays.copyOf()
會生成一個深層副本。
Arrays.copyOf()
創建一個新數組,其中包含對未被復制的對象的舊Arrays.copyOf()
,並且我添加的鏈接在嵌套數組的情況下解釋它們不會被復制,因此它不能被視為深拷貝,但淺拷貝。
有關更多信息,請參閱此
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.