Java 二维数组的四种拷贝方法

Java 二维数组的四种拷贝方法

  1. for 循环
  2. System.arrayCopy()
  3. clone() 方法
  4. Arrays.copyOf()

Java 二维数组(多维数组)的理解

参考页面 geeksforgeeks

Multidimensional Arrays can be defined in simple words as array of arrays. Data in multidimensional arrays are stored in tabular form (in row major order).

Java 多维数组可看作为数组的数组.多维数组的数据以表格的形式存储(行排序为主)

二维数组可看作为一个表格,三维数组可看作为有多层表格.

四种方法的代码示例

for 循环

/**
 * 使用 双层 for 循环 方法
 *
 * @param sourceArr 源数组
 * @param destArr   目标数组
 */
public static void copy1(int[][] sourceArr, int[][] destArr) {
    for (int i = 0; i < sourceArr.length; i++) {
        for (int j = 0; j < sourceArr[i].length; j++) {
            destArr[i][j] = sourceArr[i][j];
        }
    }
}

System.arraycopy 方法

/**
 * 使用 System.arraycopy 方法
 *
 * @param sourceArr 源数组
 * @param destArr   目标数组
 */
public static void copy2(int[][] sourceArr, int[][] destArr) {
    for (int i = 0; i < sourceArr.length; i++) {
        if (sourceArr[i].length >= 0) {
            System.arraycopy(sourceArr[i], 0, destArr[i], 0, sourceArr[i].length);
        }
    }
}

clone()

参考页面 javatpoint

Since, Java array implements the Cloneable interface, we can create the clone of the Java array. If we create the clone of a single-dimensional array, it creates the deep copy of the Java array. It means, it will copy the actual value. But, if we create the clone of a multidimensional array, it creates the shallow copy of the Java array which means it copies the references.

由于Java数组实现了Cloneable接口,因此我们可以创建Java数组的克隆。 如果我们创建一维数组的克隆,它会创建Java数组的深层副本(深拷贝)。 这意味着,它将复制实际值。 但是,如果我们创建多维数组的克隆,它会创建Java数组的浅层副本(浅拷贝),这意味着它会复制引用。

/**
 * 使用数组本身的 clone() 方法
 *
 * @param sourceArr 源数组
 * @param destArr   目标数组
 */
public static void copy3(int[][] sourceArr, int[][] destArr) {
    for (int i = 0; i < sourceArr.length; i++) {
        destArr[i] = sourceArr[i].clone();
    }
}

Arrays.copyOf()

/**
 * 使用 Arrays.copyOf 方法
 *
 * @param sourceArr 源数组
 * @param destArr   目标数组
 */
public static void copy4(int[][] sourceArr, int[][] destArr) {
    for (int i = 0; i < sourceArr.length; i++) {
        destArr[i] = Arrays.copyOf(sourceArr[i], sourceArr[i].length);
    }
}

测试代码

@Test
public void test() {
    int n = 10000;
    // 创建一个 n * n 的二维数组
    int[][] arr = new int[n][n];
    // 进行填充
    for (int i = 0; i < arr.length; i++) {
        for (int j = 0; j < arr.length; j++) {
            arr[i][j] = (int) (Math.random() * 10);
        }
    }
    // 进行拷贝,测试时间

    // for
    {
        Instant start = Instant.now();
        copy1(arr, new int[n][n]);
        Instant end = Instant.now();
        System.out.println(String.format("%20s", "for:") + Duration.between(start, end).toMillis() + " ms");
    }

    // System.arraycopy()
    {
        Instant start = Instant.now();
        copy2(arr, new int[n][n]);
        Instant end = Instant.now();
        System.out.println(String.format("%20s", "System.arraycopy():") + Duration.between(start, end).toMillis() + " ms");
    }

    // clone
    {
        Instant start = Instant.now();
        copy3(arr, new int[n][n]);
        Instant end = Instant.now();
        System.out.println(String.format("%20s", "clone():") + Duration.between(start, end).toMillis() + " ms");
    }

    // Arrays.copyOf()
    {
        Instant start = Instant.now();
        copy4(arr, new int[n][n]);
        Instant end = Instant.now();
        System.out.println(String.format("%20s", "Arrays.copyOf():") + Duration.between(start, end).toMillis() + " ms");
    }
}

测试结果

>> 数据规模 10000 * 10000

----------------第一组----------------

               for:378 ms
System.arraycopy():264 ms
           clone():542 ms
   Arrays.copyOf():487 ms

----------------第二组----------------

               for:472 ms
System.arraycopy():298 ms
           clone():516 ms
   Arrays.copyOf():513 ms

----------------第三组----------------

               for:432 ms
System.arraycopy():388 ms
           clone():552 ms
   Arrays.copyOf():562 ms


>> System.arraycopy 的效率最高

查看 System.arraycopy 的源代码

@HotSpotIntrinsicCandidate
public static native void arraycopy(Object src,  int  srcPos,
                                    Object dest, int destPos,
                                    int length);

由于被 native 修饰,可知这是一个本地方法(由c/c++编写),故总结效率很高(如果理解有差错,还请更正,感谢)

发布了80 篇原创文章 · 获赞 13 · 访问量 9251

猜你喜欢

转载自blog.csdn.net/qq_39424178/article/details/100135381
今日推荐