java数组的四种拷贝方式

2021-04-21 14:25:15 浏览数 (1)

参考链接: Java复制数组

文章目录

 一维数组for循环拷贝数值类型拷贝引用类型

   clone()拷贝数值方式拷贝引用类型

   System.arraycopy()拷贝数值类型拷贝引用类型

   Arrays.copyof()拷贝数值类型拷贝引用类型

  二维数组for循环拷贝数值类型拷贝引用类型

   clone()拷贝数值类型拷贝引用类型

   System.arraycopy()拷贝数值类型拷贝引用类型

   Arrays.copyof()拷贝数值类型拷贝引用类型

  源码分析forclone()System.arraycopy()Arrays.copyof()

 数组的拷贝方式有四种,分别是:

 for循环    clone()   System.arraycopy()    Arrays.copyof()

一维数组 

for循环 

拷贝数值类型 

    int[] array = {1,2,3,4,5,6};

        int[] array2 = new int[6];

        for (int i = 0; i < array.length; i ) {

            array2[i] = array[i];

        }

        System.out.println("拷贝数值类型:");

        System.out.println(Arrays.toString(array));

        System.out.println(Arrays.toString(array2));

        System.out.println("--------------修改后--------------------");

        array2[0] = 0;

        System.out.println(Arrays.toString(array));

        System.out.println(Arrays.toString(array2));

下面是运行结果:  

拷贝引用类型 

public class Arraycopy {

    public static void main(String[] args) {

        TestArray[] arrays = new TestArray[4];

        arrays[0] = new TestArray(1);

        arrays[1] = new TestArray(2);

        arrays[2] = new TestArray(3);

        arrays[3] = new TestArray(4);

        TestArray[] arrays2 = new TestArray[4];

        for (int i = 0; i < arrays.length; i ) {

            arrays2[i] = arrays[i];

        }

        System.out.println("拷贝引用类型:");

        show(arrays);

        show(arrays2);

        System.out.println("--------------修改后--------------------");

        arrays2[0].setData(0);

        show(arrays);

        show(arrays2);

    }

    public static void show(TestArray[] arrays) {

        for (int i = 0; i < arrays.length; i ) {

            System.out.print(arrays[i].getData() " ");

        }

        System.out.println();

    }

}

class TestArray {

    private int data;

    public TestArray(int data) {

        this.data = data;

    }

    public int getData() {

        return data;

    }

    public void setData(int data) {

        this.data = data;

    }

}

clone() 

拷贝数值方式 

    int[] array = {1,2,3,4,5,6};

        int[] array2 = new int[6];

        array2 = array.clone();

        System.out.println("拷贝数值类型:");

        System.out.println(Arrays.toString(array));

        System.out.println(Arrays.toString(array2));

        System.out.println("--------------修改后--------------------");

        array2[0] = 0;

        System.out.println(Arrays.toString(array));

        System.out.println(Arrays.toString(array2));

拷贝引用类型 

    TestArray[] arrays = new TestArray[4];

        arrays[0] = new TestArray(1);

        arrays[1] = new TestArray(2);

        arrays[2] = new TestArray(3);

        arrays[3] = new TestArray(4);

        TestArray[] arrays2 = new TestArray[4];

        arrays2 = arrays.clone();

        System.out.println("拷贝引用类型:");

        show(arrays);

        show(arrays2);

        System.out.println("--------------修改后--------------------");

        arrays2[0].setData(0);

        show(arrays);

        show(arrays2);

System.arraycopy() 

拷贝数值类型 

    int[] array = {1,2,3,4,5,6};

        int[] array2 = new int[6];

        System.arraycopy(array,0,array2,0,array.length);

        System.out.println("拷贝数值类型:");

        System.out.println(Arrays.toString(array));

        System.out.println(Arrays.toString(array2));

        System.out.println("--------------修改后--------------------");

        array2[0] = 0;

        System.out.println(Arrays.toString(array));

        System.out.println(Arrays.toString(array2));

拷贝引用类型 

    TestArray[] arrays = new TestArray[4];

        arrays[0] = new TestArray(1);

        arrays[1] = new TestArray(2);

        arrays[2] = new TestArray(3);

        arrays[3] = new TestArray(4);

        TestArray[] arrays2 = new TestArray[arrays.length];

        System.arraycopy(arrays,0,arrays2,0,arrays.length);

        arrays2 = arrays.clone();

        System.out.println("拷贝引用类型:");

        show(arrays);

        show(arrays2);

        System.out.println("--------------修改后--------------------");

        arrays2[0].setData(0);

        show(arrays);

        show(arrays2);

Arrays.copyof() 

拷贝数值类型 

    int[] array = {1,2,3,4,5,6};

        int[] array2 = new int[6];

        array2 = Arrays.copyOf(array,array.length);

        System.out.println("拷贝数值类型:");

        System.out.println(Arrays.toString(array));

        System.out.println(Arrays.toString(array2));

        System.out.println("--------------修改后--------------------");

        array2[0] = 0;

        System.out.println(Arrays.toString(array));

        System.out.println(Arrays.toString(array2));

拷贝引用类型 

    TestArray[] arrays = new TestArray[4];

        arrays[0] = new TestArray(1);

        arrays[1] = new TestArray(2);

        arrays[2] = new TestArray(3);

        arrays[3] = new TestArray(4);

        TestArray[] arrays2 = new TestArray[4];

        arrays2 = Arrays.copyOf(arrays,arrays.length);

        System.out.println("拷贝引用类型:");

        show(arrays);

        show(arrays2);

        System.out.println("--------------修改后--------------------");

        arrays2[0].setData(0);

        show(arrays);

        show(arrays2);

二维数组 

for循环 

拷贝数值类型 

    int[][] array = {{1,2,3},{4,5,6}};

        int[][] array2 = new int[2][3];

        for (int i = 0; i < array.length; i ) {

            for (int j = 0; j < array[i].length; j ) {

                array2[i][j] = array[i][j];

            }

        }

        System.out.println("拷贝数值类型:");

        System.out.println(Arrays.deepToString(array));

        System.out.println(Arrays.deepToString(array2));

        System.out.println("--------------修改后--------------------");

        array2[0][0] = 0;

        System.out.println(Arrays.deepToString(array));

        System.out.println(Arrays.deepToString(array2));

拷贝引用类型 

public class TwoArrayCopy {

    public static void main(String[] args) {

        TestArray[][] arrays = new TestArray[2][2];

        arrays[0][0] = new TestArray(1);

        arrays[0][1] = new TestArray(2);

        arrays[1][0] = new TestArray(3);

        arrays[1][1] = new TestArray(4);

        TestArray[][] arrays2 = new TestArray[2][2];

        for (int i = 0; i < arrays.length; i ) {

            for (int j = 0; j < arrays[i].length; j ) {

                arrays2[i][j] = arrays[i][j];

            }

        }

        System.out.println("拷贝引用类型:");

        show(arrays);

        show(arrays2);

        System.out.println("--------------修改后--------------------");

        arrays2[0][0].setData(0);

        show(arrays);

        show(arrays2);

    }

    public static void show(TestArray[][] arrays) {

        for (int i = 0; i < arrays.length; i ) {

            for (int j = 0; j < arrays[i].length; j ) {

                System.out.print(arrays[i][j].getData() " ");

            }

            System.out.println();

        }

    }

}

class TestArray {

    private int data;

    public TestArray(int data) {

        this.data = data;

    }

    public int getData() {

        return data;

    }

    public void setData(int data) {

        this.data = data;

    }

}

clone() 

拷贝数值类型 

    int[][] array = {{1,2,3},{4,5,6}};

        int[][] array2 = new int[2][3];

        for (int i = 0; i < array.length; i ) {

            array2[i] = array[i].clone();

        }

        System.out.println("拷贝数值类型:");

        System.out.println(Arrays.deepToString(array));

        System.out.println(Arrays.deepToString(array2));

        System.out.println("--------------修改后--------------------");

        array2[0][0] = 0;

        System.out.println(Arrays.deepToString(array));

        System.out.println(Arrays.deepToString(array2));

拷贝引用类型 

    TestArray[][] arrays = new TestArray[2][2];

        arrays[0][0] = new TestArray(1);

        arrays[0][1] = new TestArray(2);

        arrays[1][0] = new TestArray(3);

        arrays[1][1] = new TestArray(4);

        TestArray[][] arrays2 = new TestArray[2][2];

        for (int i = 0; i < arrays.length; i ) {

            arrays2[i] = arrays[i].clone();

        }

        System.out.println("拷贝引用类型:");

        show(arrays);

        show(arrays2);

        System.out.println("--------------修改后--------------------");

        arrays2[0][0].setData(0);

        show(arrays);

        show(arrays2);

System.arraycopy() 

拷贝数值类型 

    int[][] array = {{1,2,3},{4,5,6}};

        int[][] array2 = new int[2][3];

        for (int i = 0; i < array.length; i ) {

            System.arraycopy(array[i],0,array2[i],0,array[i].length);

        }

        System.out.println("拷贝数值类型:");

        System.out.println(Arrays.deepToString(array));

        System.out.println(Arrays.deepToString(array2));

        System.out.println("--------------修改后--------------------");

        array2[0][0] = 0;

        System.out.println(Arrays.deepToString(array));

        System.out.println(Arrays.deepToString(array2));

拷贝引用类型 

    TestArray[][] arrays = new TestArray[2][2];

        arrays[0][0] = new TestArray(1);

        arrays[0][1] = new TestArray(2);

        arrays[1][0] = new TestArray(3);

        arrays[1][1] = new TestArray(4);

        TestArray[][] arrays2 = new TestArray[2][2];

        for (int i = 0; i < arrays.length; i ) {

            System.arraycopy(arrays[i],0,arrays2[i],0,arrays[i].length);

        }

        System.out.println("拷贝引用类型:");

        show(arrays);

        show(arrays2);

        System.out.println("--------------修改后--------------------");

        arrays2[0][0].setData(0);

        show(arrays);

        show(arrays2);

Arrays.copyof() 

拷贝数值类型 

    int[][] array = {{1,2,3},{4,5,6}};

        int[][] array2 = new int[2][3];

        for (int i = 0; i < array.length; i ) {

            array2[i] = Arrays.copyOf(array[i],array[i].length);

        }

        System.out.println("拷贝数值类型:");

        System.out.println(Arrays.deepToString(array));

        System.out.println(Arrays.deepToString(array2));

        System.out.println("--------------修改后--------------------");

        array2[0][0] = 0;

        System.out.println(Arrays.deepToString(array));

        System.out.println(Arrays.deepToString(array2));

拷贝引用类型 

    TestArray[][] arrays = new TestArray[2][2];

        arrays[0][0] = new TestArray(1);

        arrays[0][1] = new TestArray(2);

        arrays[1][0] = new TestArray(3);

        arrays[1][1] = new TestArray(4);

        TestArray[][] arrays2 = new TestArray[2][2];

        for (int i = 0; i < arrays.length; i ) {

            arrays2[i] = Arrays.copyOf(arrays[i],arrays[i].length);

        }

        System.out.println("拷贝引用类型:");

        show(arrays);

        show(arrays2);

        System.out.println("--------------修改后--------------------");

        arrays2[0][0].setData(0);

        show(arrays);

        show(arrays2);

源码分析 

for 

for循环是一种很灵巧的数组拷贝方式,经常可以自己封装成方法去使用。 

clone() 

克隆方法我们在数组中是找不到的,它是object的方法,我们先看看源码 

    protected native Object clone() throws CloneNotSupportedException;

看到了修饰符native,说明是由c或者c 实现的,它的优点是速度快,它返回了object对象,所以使用的时候需要用对象接收返回值。 

System.arraycopy() 

通过System类调用的静态方法,我们先看看源码 

public static native void arraycopy(Object src,  int  srcPos,

                                        Object dest, int destPos,

                                        int length);

先来解释一下这些形参代表的意思,src代表被拷贝的对象,srcPos代表起始位置,dest代表目标对象,destpost代表目标对象的起始位置,length代表拷贝的长度。我们看到也是native修饰的,所以底层也是用c或者c 实现的,但是可以看到没有返回值,clone()还需要对返回值进行类型转换,所以它的速度是要比clone()要快的,这也是牛客网的一道题,问的就是四种拷贝哪种是最快的,答案肯定是System.arraycopy()。 

Arrays.copyof() 

这个方法是属于Arrays类的,我们先来看看源码是怎样实现的,在源码中提供了很多方法的重载,无非就是对于类型的一些替换,比如int数组,byte数组等等,就不一一列举了,我们写出常用的一个方法 

    public static int[] copyOf(int[] original, int newLength) {

        int[] copy = new int[newLength];

        System.arraycopy(original, 0, copy, 0,

                         Math.min(original.length, newLength));      

                           return copy;

    }

我们可以看到,在方法内部调用了System.arraycopy(),只是相当于重写了一下,换了一个名字。解释一下形参,original是待拷贝对象,newLength表示拷贝的长度,当然还有Arrays.copyOfRange(),就是可以控制拷贝的范围,不过我认为可以常用System.arraycopy(),这样什么情况都可以解决。

0 人点赞