数组的复制
数组复制是指将一个数组中的元素拷贝到另一个数组中。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)。
原理说明:
所谓”扩容”并不是真正改变原数组的长度,而是:
- 创建一个长度更大的新数组
- 将原数组中的所有元素复制到新数组中
- 将变量
a指向新数组 - 原数组由于没有引用指向它,会被垃圾回收
三种方式对比
| 方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 手动遍历 | 灵活,可自定义复制逻辑 | 代码量多,效率较低 | 需要选择性复制或转换时 |
System.arraycopy() | 效率高,JVM 本地方法 | 参数多,需提前创建目标数组 | 已知目标数组,追求性能 |
Arrays.copyOf() | 简洁,一行完成 | 需 import,每次创建新数组 | 快速复制或”扩容” |
注意事项
| 要点 | 说明 |
|---|---|
| 浅拷贝 | 以上三种方式都是浅拷贝,引用类型数组复制的是引用地址,而非对象本身 |
| 数组越界 | System.arraycopy() 中参数若超出数组范围会抛 ArrayIndexOutOfBoundsException |
NullPointerException | 源数组或目标数组为 null 时会抛异常 |
| 基本类型 vs 引用类型 | 基本类型复制值互不影响;引用类型复制后两个数组指向同一批对象 |
Previous: 数组的访问