java数组的四种拷贝方式

文章目录

  • 一维数组
    • for循环
      • 拷贝数值类型
      • 拷贝引用类型
    • clone()
      • 拷贝数值方式
      • 拷贝引用类型
    • System.arraycopy()
      • 拷贝数值类型
      • 拷贝引用类型
    • Arrays.copyof()
      • 拷贝数值类型
      • 拷贝引用类型
  • 二维数组
    • for循环
      • 拷贝数值类型
      • 拷贝引用类型
    • clone()
      • 拷贝数值类型
      • 拷贝引用类型
    • System.arraycopy()
      • 拷贝数值类型
      • 拷贝引用类型
    • Arrays.copyof()
      • 拷贝数值类型
      • 拷贝引用类型
  • 源码分析
    • for
    • clone()
    • 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));

下面是运行结果:
java数组的四种拷贝方式_第1张图片

拷贝引用类型

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;
    }
}

java数组的四种拷贝方式_第2张图片

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));

java数组的四种拷贝方式_第3张图片

拷贝引用类型

	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);

java数组的四种拷贝方式_第4张图片

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));

java数组的四种拷贝方式_第5张图片

拷贝引用类型

	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);

java数组的四种拷贝方式_第6张图片

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));

java数组的四种拷贝方式_第7张图片

拷贝引用类型

	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);

java数组的四种拷贝方式_第8张图片

二维数组

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));

java数组的四种拷贝方式_第9张图片

拷贝引用类型

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;
    }
}

java数组的四种拷贝方式_第10张图片

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));

java数组的四种拷贝方式_第11张图片

拷贝引用类型

	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);

java数组的四种拷贝方式_第12张图片

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));

java数组的四种拷贝方式_第13张图片

拷贝引用类型

	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);

java数组的四种拷贝方式_第14张图片

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));

java数组的四种拷贝方式_第15张图片

拷贝引用类型

	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);

java数组的四种拷贝方式_第16张图片

源码分析

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(),这样什么情况都可以解决。

你可能感兴趣的:(JavaSE)