数组的复制

数组的复制

数组复制是指将一个数组中的元素拷贝到另一个数组中。Java 中既可以通过手动遍历实现,也可以使用系统提供的工具方法完成。

方式一:手动遍历复制

public static void main(String[] args) {
    int[] a = {345, 34, 23, 5, 23, 645, 75, 8, 345, 45, 768, 23, 45, 6, 434, 57, 45, 646};
    int[] b = new int[a.length];
    for (int i = 0; i < a.length; i++) {
        b[i] = a[i];
    }
    for (int i = 0; i < b.length; i++) {
        System.out.println(b[i]);
    }
}Code language: JavaScript (javascript)

方式二:System.arraycopy() 方法

System.arraycopy() 是 JVM 提供的本地方法,效率较高,有五个参数:

参数说明
源数组被复制的原始数组
源数组起始下标从源数组的哪个位置开始复制
目标数组复制到的目标数组
目标数组起始下标从目标数组的哪个位置开始存放
复制元素个数一共复制多少个元素
public static void main(String[] args) {
    int[] a = {345, 34, 23, 5, 23, 645, 75, 8, 345, 45, 768, 23, 45, 6, 434, 57, 45, 646};
    int[] b = new int[a.length];
    System.arraycopy(a, 0, b, 0, a.length);
    for (int i = 0; i < b.length; i++) {
        System.out.println(b[i]);
    }
}Code language: JavaScript (javascript)

注意:如果源数组和目标数组有重叠区域,该方法能正确处理,不会造成数据覆盖错误。

方式三:Arrays.copyOf() 方法

Arrays.copyOf() 位于 java.util.Arrays 类中,需要 import。它内部调用了 System.arraycopy(),使用更简洁:

import java.util.Arrays;

public static void main(String[] args) {
    int[] a = {345, 34, 23, 5, 23, 645, 75, 8, 345, 45, 768, 23, 45, 6, 434, 57, 45, 646};
    int[] b = Arrays.copyOf(a, a.length);
    for (int i = 0; i < b.length; i++) {
        System.out.println(b[i]);
    }
}Code language: JavaScript (javascript)

利用 Arrays.copyOf() 实现数组”扩容”

数组一旦创建长度就不可改变,Arrays.copyOf() 可以通过创建新数组来实现”扩容”效果:

import java.util.Arrays;

public static void main(String[] args) {
    int[] a = {345, 34, 23, 5, 23};
    a = Arrays.copyOf(a, a.length + 1); // 长度从 5 扩展为 6
    for (int i = 0; i < a.length; i++) {
        System.out.println(a[i]);
    }
}Code language: JavaScript (javascript)

输出:

345
34
23
5
23
0

新扩展的位置元素取默认值(int 为 0)。

原理说明:

所谓”扩容”并不是真正改变原数组的长度,而是:

  1. 创建一个长度更大的新数组
  2. 将原数组中的所有元素复制到新数组中
  3. 将变量 a 指向新数组
  4. 原数组由于没有引用指向它,会被垃圾回收

三种方式对比

方式优点缺点适用场景
手动遍历灵活,可自定义复制逻辑代码量多,效率较低需要选择性复制或转换时
System.arraycopy()效率高,JVM 本地方法参数多,需提前创建目标数组已知目标数组,追求性能
Arrays.copyOf()简洁,一行完成需 import,每次创建新数组快速复制或”扩容”

注意事项

要点说明
浅拷贝以上三种方式都是浅拷贝,引用类型数组复制的是引用地址,而非对象本身
数组越界System.arraycopy() 中参数若超出数组范围会抛 ArrayIndexOutOfBoundsException
NullPointerException源数组或目标数组为 null 时会抛异常
基本类型 vs 引用类型基本类型复制值互不影响;引用类型复制后两个数组指向同一批对象

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注