1. 程式人生 > >java 基礎——一維陣列的拷貝

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() 基本型別是深拷貝,對於引用型別來說是淺拷貝