java 基礎——一維陣列的拷貝
文章目錄
深拷貝
深拷貝會拷貝所有的屬性,並拷貝屬性指向的動態分配的記憶體。當物件和它所引用的物件一起拷貝時即發生深拷貝。深拷貝相比於淺拷貝速度較慢並且花銷較大。
淺拷貝
淺拷貝是按位拷貝物件,它會建立一個新物件,這個物件有著原始物件屬性值的一份精確拷貝。如果屬性是基本型別,拷貝的就是基本型別的值;如果屬性是記憶體地址(引用型別),拷貝的就是記憶體地址 ,因此如果其中一個物件改變了這個地址,就會影響到另一個物件。
陣列五種拷貝方式
for迴圈拷貝
基本型別
public static void main(String[] args) { int[] array1 = {1,5,6,2,3,8}; int[] array2 = new int[array1.length]; System.out.println("陣列1 :"+Arrays.toString(array1)); for(int i = 0;i < array1.length;i++){ array2[i] = array1[i]; } System.out.println("陣列2 "+Arrays.toString(array2)); System.out.println("===改變後==="); array2[0] = 1000; System.out.println("陣列1 "+Arrays.toString(array1)); System.out.println("陣列2 "+Arrays.toString(array2)); }
執行結果:
陣列1 :[1, 5, 6, 2, 3, 8]
陣列2 [1, 5, 6, 2, 3, 8]
=改變後=
陣列1 [1, 5, 6, 2, 3, 8]
陣列2 [1000, 5, 6, 2, 3, 8]
引用型別
public static void main(String[] args) { test[] array1 = {new test(),new test(),new test()}; test[] array2 = new test[array1.length]; System.out.print("陣列1:"); show(array1); for(int i = 0;i < array1.length;i++){ array2[i] = array1[i]; } array2[0].setVal(30); System.out.print("陣列2:"); show(array2); System.out.println("===修改後==="); System.out.print("陣列1:"); show(array1); System.out.print("陣列2:"); show(array2); }
執行結果:
陣列1:[10,10,10,}
陣列2:[30,10,10,}
=修改後=
陣列1:[30,10,10,}
陣列2:[30,10,10,}
總結
從上面的例子我們可以看出:for 迴圈啊拷貝基本型別陣列的時候,改變其中一個並沒有改變另外一個,所以拷貝基本型別是深拷貝。for 迴圈拷貝引用型別陣列的時候,改變其中一個會影響另外一個,所以拷貝引用型別的是淺拷貝。
clone拷貝方式
基本型別
public static void main(String[] args) {
int[] array1 = {10,10,10};
int[] array2 = new int[array1.length];
array2 = array1.clone();
System.out.println("陣列1:"+ Arrays.toString(array1));
System.out.println("陣列2:"+ Arrays.toString(array2));
array2[0] = 30;
System.out.println("===修改後===");
System.out.println("陣列1:"+ Arrays.toString(array1));
System.out.println("陣列2:"+ Arrays.toString(array2));
}
執行結果:
陣列1:[10, 10, 10]
陣列2:[10, 10, 10]
=修改後=
陣列1:[10, 10, 10]
陣列2:[30, 10, 10]
引用型別
public static void main(String[] args) {
test[] array1 = {new test(),new test(),new test()};
test[] array2 = new test[array1.length];
array2 = array1.clone();
System.out.print("陣列1:");
show(array1);
System.out.print("陣列2:");
show(array2);
array2[0].setVal(30);
System.out.println("===修改後===");
System.out.print("陣列1:");
show(array1);
System.out.print("陣列2:");
show(array2);
}
執行結果:
陣列1:[10,10,10,}
陣列2:[10,10,10,}
=修改後=
陣列1:[30,10,10,}
陣列2:[30,10,10,}
總結
clone 方式拷貝陣列對於基本型別來說改變其中一個並沒有改變另外一個,對於引用型別來說,改變其中一個也影響了另外一個。所以clone基本型別是深拷貝,對於引用型別來說是淺拷貝。
Sysout.arraycopy()
相對較快的拷貝方法,native 方法。
基本型別
arraycopy(Object src,int srcPos,Object dest,int destPos,int length);
src :源陣列。
srcPos : 源陣列的開始位置0, 開始拷貝位置
dest :拷貝到目標陣列。
destPos :拷貝到目標陣列的位置。
lenght : 源陣列拷多大。
public static void main(String[] args) {
int[] array1 = {10,10,10};
int[] array2 = new int[array1.length];
System.arraycopy(array1,0,array2,0,array1.length);
System.out.println("陣列1:"+ Arrays.toString(array1));
System.out.println("陣列2:"+ Arrays.toString(array2));
array2[0] = 30;
System.out.println("===修改後===");
System.out.println("陣列1:"+ Arrays.toString(array1));
System.out.println("陣列2:"+ Arrays.toString(array2));
}
執行結果:
陣列1:[10, 10, 10]
陣列2:[10, 10, 10]
=修改後=
陣列1:[10, 10, 10]
陣列2:[30, 10, 10]
引用型別
public static void main(String[] args) {
test[] array1 = {new test(),new test(),new test()};
test[] array2 = new test[array1.length];
System.arraycopy(array1,0,array2,0,array1.length);
System.out.print("陣列1:");
show(array1);
System.out.print("陣列2:");
show(array2);
array2[0].setVal(30);
System.out.println("===修改後===");
System.out.print("陣列1:");
show(array1);
System.out.print("陣列2:");
show(array2);
}
執行結果:
陣列1:[10,10,10,}
陣列2:[10,10,10,}
=修改後=
陣列1:[30,10,10,}
陣列2:[30,10,10,}
總結
System.arraycopy() 方式拷貝陣列對於基本型別來說改變其中一個並沒有改變另外一個,對於引用型別來說,改變其中一個也影響了另外一個。所以clone基本型別是深拷貝,對於引用型別來說是淺拷貝。
Arrays.copyOf(T[] original, int newLength)
T[] original:原始陣列。
int newLength:新的陣列長度。
基本型別
public static void main(String[] args) {
int[] array1 = {10,10,10};
int[] array2 = new int[array1.length];
array2 = Arrays.copyOf(array1,array1.length);
System.out.println("陣列1:"+ Arrays.toString(array1));
System.out.println("陣列2:"+ Arrays.toString(array2));
array2[0] = 30;
System.out.println("===修改後===");
System.out.println("陣列1:"+ Arrays.toString(array1));
System.out.println("陣列2:"+ Arrays.toString(array2));
}
執行結果:
陣列1:[10, 10, 10]
陣列2:[10, 10, 10]
=修改後=
陣列1:[10, 10, 10]
陣列2:[30, 10, 10]
引用型別
public static void main(String[] args) {
test[] array1 = {new test(),new test(),new test()};
test[] array2 = new test[array1.length];
array2 = Arrays.copyOf(array1,array1.length);
System.out.print("陣列1:");
show(array1);
System.out.print("陣列2:");
show(array2);
array2[0].setVal(30);
System.out.println("===修改後===");
System.out.print("陣列1:");
show(array1);
System.out.print("陣列2:");
show(array2);
}
執行結果:
陣列1:[10,10,10,}
陣列2:[10,10,10,}
=修改後=
陣列1:[30,10,10,}
陣列2:[30,10,10,}
總結
Arrays.copyOf() 方式拷貝陣列對於基本型別來說改變其中一個並沒有改變另外一個,對於引用型別來說,改變其中一個也影響了另外一個。所以Arrays.copyOf() 基本型別是深拷貝,對於引用型別來說是淺拷貝。