原文: https://www.programiz.com/java-programming/copy-arrays

在本教程中,您将在示例的帮助下了解可用于在 Java 中复制数组(一维和二维)的不同方法。

在 Java 中,我们可以将一个数组复制到另一个数组中。 您可以使用多种技术来复制 Java 中的数组。


1.使用赋值运算符复制数组

让我们举个例子

  1. class Main {
  2. public static void main(String[] args) {
  3. int [] numbers = {1, 2, 3, 4, 5, 6};
  4. int [] positiveNumbers = numbers; // copying arrays
  5. for (int number: positiveNumbers) {
  6. System.out.print(number + ", ");
  7. }
  8. }
  9. }

输出

  1. 1, 2, 3, 4, 5, 6

在上面的示例中,我们使用赋值运算符(=)将名为numbers的数组复制到名为positiveNumbers的另一个数组。

此技术是最简单的一种,它也可以正常工作。 但是,该技术存在问题。 如果我们更改一个数组的元素,则其他数组的相应元素也会更改。 例如,

  1. class Main {
  2. public static void main(String[] args) {
  3. int [] numbers = {1, 2, 3, 4, 5, 6};
  4. int [] positiveNumbers = numbers; // copying arrays
  5. // change value of first array
  6. numbers[0] = -1;
  7. // printing the second array
  8. for (int number: positiveNumbers) {
  9. System.out.print(number + ", ");
  10. }
  11. }
  12. }

输出

  1. -1, 2, 3, 4, 5, 6

在这里,我们可以看到我们更改了number数组的一个值。 当我们打印positiveNumbers数组时,我们可以看到相同的值也已更改。

这是因为两个数组都引用同一个数组对象。 这是因为复制浅。 要了解有关浅拷贝的更多信息,请访问浅拷贝

现在,要在复制数组时创建新的数组对象,我们需要深层复制而不是浅层复制。


2.使用循环结构复制数组

让我们举个例子:

  1. import java.util.Arrays;
  2. class Main {
  3. public static void main(String[] args) {
  4. int [] source = {1, 2, 3, 4, 5, 6};
  5. int [] destination = new int[6];
  6. // iterate and copy elements from source to destination
  7. for (int i = 0; i < source.length; ++i) {
  8. destination[i] = source[i];
  9. }
  10. // converting array to string
  11. System.out.println(Arrays.toString(destination));
  12. }
  13. }

输出

  1. [1, 2, 3, 4, 5, 6]

在上面的示例中,我们使用for循环迭代源数组的每个元素。 在每次迭代中,我们都将元素从source数组复制到destination数组。

在此,源数组和目标数组引用不同的对象(深复制)。 因此,如果一个数组的元素改变,则另一数组的相应元素不变。

注意声明,

  1. System.out.println(Arrays.toString(destination));

在这里,toString()方法用于将数组转换为字符串。 要了解更多信息,请访问toString()方法(Java 官方文档)


3.使用arraycopy()方法复制数组

在 Java 中,系统类包含一个名为arraycopy()的方法来复制数组。 与上述两种方法相比,此方法是复制数组的更好方法。

arraycopy()方法允许您将源数组的指定部分复制到目标数组。 例如,

  1. arraycopy(Object src, int srcPos,Object dest, int destPos, int length)

这里,

  • src - 您要复制的源数组
  • srcPos - 源数组中的起始位置(索引)
  • dest - 将要从源复制元素的目标数组
  • destPos - 目标数组中的起始位置(索引)
  • length - 要复制的元素数

Let’s take an example:

  1. // To use Arrays.toString() method
  2. import java.util.Arrays;
  3. class Main {
  4. public static void main(String[] args) {
  5. int[] n1 = {2, 3, 12, 4, 12, -2};
  6. int[] n3 = new int[5];
  7. // Creating n2 array of having length of n1 array
  8. int[] n2 = new int[n1.length];
  9. // copying entire n1 array to n2
  10. System.arraycopy(n1, 0, n2, 0, n1.length);
  11. System.out.println("n2 = " + Arrays.toString(n2));
  12. // copying elements from index 2 on n1 array
  13. // copying element to index 1 of n3 array
  14. // 2 elements will be copied
  15. System.arraycopy(n1, 2, n3, 1, 2);
  16. System.out.println("n3 = " + Arrays.toString(n3));
  17. }
  18. }

输出

  1. n2 = [2, 3, 12, 4, 12, -2]
  2. n3 = [0, 12, 4, 0, 0]

在上面的示例中,我们使用了arraycopy()方法,

  • System.arraycopy(n1, 0, n2, 0, n1.length) - 将n1数组中的整个元素复制到n2数组中
  • System.arraycopy(n1, 2, n3, 1, 2) - 从索引2开始的n1数组的 2 个元素被复制到从索引1开始的n3数组

如您所见,int类型数组的元素的默认初始值为 0。


4.使用copyOfRange()方法复制数组

我们还可以使用 Java Arrays类中定义的copyOfRange()方法来复制数组。 例如,

// To use toString() and copyOfRange() method
import java.util.Arrays;

class ArraysCopy {
    public static void main(String[] args) {

        int[] source = {2, 3, 12, 4, 12, -2};

        // copying entire source array to destination
        int[] destination1 = Arrays.copyOfRange(source, 0, source.length);      
        System.out.println("destination1 = " + Arrays.toString(destination1)); 

        // copying from index 2 to 5 (5 is not included) 
        int[] destination2 = Arrays.copyOfRange(source, 2, 5); 
        System.out.println("destination2 = " + Arrays.toString(destination2));   
    }
}

输出

destination1 = [2, 3, 12, 4, 12, -2]
destination2 = [12, 4, 12]

在上面的示例中,请注意以下行:

int[] destination1 = Arrays.copyOfRange(source, 0, source.length);

在这里,我们可以看到正在创建destination1数组,并将source数组同时复制到该数组。 在调用copyOfRange()方法之前,我们不会创建destination1数组。 要了解有关该方法的更多信息,请访问 Java copyOfRange


5.使用循环复制二维数组

类似于一维数组,我们还可以使用for循环复制二维数组。 例如,

import java.util.Arrays;

class Main {
    public static void main(String[] args) {

        int[][] source = {
              {1, 2, 3, 4}, 
              {5, 6},
              {0, 2, 42, -4, 5}
              };

        int[][] destination = new int[source.length][];

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

            // allocating space for each row of destination array
            destination[i] = new int[source[i].length];

            for (int j = 0; j < destination[i].length; ++j) {
                destination[i][j] = source[i][j];
            }
        }

        // displaying destination array
        System.out.println(Arrays.deepToString(destination));  

    }
}

输出

[[1, 2, 3, 4], [5, 6], [0, 2, 42, -4, 5]]

在上面的程序中,请注意以下行:

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

在此,deepToString()方法用于更好地表示二维数组。 要了解更多信息,请访问 Java deepToString())。


使用arraycopy()复制 2d 数组

为了使上面的代码更简单,我们可以将内部循环替换为System.arraycopy(),就像一维数组一样。 例如,

import java.util.Arrays;

class Main {
    public static void main(String[] args) {

        int[][] source = {
              {1, 2, 3, 4}, 
              {5, 6},
              {0, 2, 42, -4, 5}
              };

        int[][] destination = new int[source.length][];

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

             // allocating space for each row of destination array
             destination[i] = new int[source[i].length];
             System.arraycopy(source[i], 0, destination[i], 0, destination[i].length);
        }

        // displaying destination array
        System.out.println(Arrays.deepToString(destination));      
    }
}

输出

[[1, 2, 3, 4], [5, 6], [0, 2, 42, -4, 5]]

在这里,我们看到通过用arraycopy()方法替换内部的for循环,我们得到了相同的输出。