数组扩容

1. 直接用循环复制

2. 使用Arrays.copy()

3. System.arraycopy() 方法进行复制

在自定义动态数组的扩容过程中,常用的元素复制方法有三种:循环复制、Arrays.copyOf() 和 System.arraycopy()。以下是它们的详细解释和区别:

==elements是数组==

1. 直接用循环复制

原理:通过 for 循环遍历原数组,将每个元素逐个复制到新数组中。

实现示例

1
2
3
4
5
6
7
8
9
private void resize() {
int newCapacity = elements.length * 2; // 假设扩容为原来的2倍
Object[] newElements = new Object[newCapacity];
// 循环复制元素
for (int i = 0; i < size; i++) {
newElements[i] = elements[i];
}
elements = newElements; // 替换为新数组
}

特点

  • 实现简单直观,适合初学者理解
  • 性能较差(纯 Java 代码循环,效率低于底层优化的方法)
  • 灵活性高,可在复制过程中添加额外逻辑(如过滤、转换元素)

2. 使用 Arrays.copyOf() 方法

原理:Java 提供的工具类方法,内部通过 System.arraycopy() 实现,简化了复制逻辑。

实现示例

1
2
3
4
5
6
7
import java.util.Arrays;

private void resize() {
int newCapacity = elements.length * 2;
// 直接生成新数组并复制元素(自动处理长度)
elements = Arrays.copyOf(elements, newCapacity);
}

特点

  • 代码简洁,一行即可完成数组复制和扩容
  • 内部依赖 System.arraycopy(),性能较好
  • 会自动处理原数组与新数组的长度差异(若新数组更长,多余位置填默认值 null
  • 属于 java.util.Arrays 工具类,需导入包

3. 使用 System.arraycopy() 方法

原理:Java 底层 native 方法(本地方法,由 C/C++ 实现),直接操作内存块,效率极高。

实现示例

1
2
3
4
5
6
7
private void resize() {
int newCapacity = elements.length * 2;
Object[] newElements = new Object[newCapacity];
// 本地方法复制:原数组、原数组起始位置、新数组、新数组起始位置、复制长度
System.arraycopy(elements, 0, newElements, 0, size);
elements = newElements;
}

特点

  • 性能最优(底层直接操作内存,无 Java 层循环开销)
  • 需手动创建新数组,参数较多(原数组、源起始索引、目标数组、目标起始索引、复制长度)
  • 适合对性能要求高的场景,是 ArrayList 等 Java 集合的底层实现方式

三者对比

方法 性能 代码简洁度 灵活性 适用场景
循环复制 简单场景、需自定义复制逻辑
Arrays.copyOf() 日常开发,追求代码简洁
System.arraycopy() 最高 底层实现、高性能要求场景

实际开发中,推荐优先使用 Arrays.copyOf()(简洁)或 System.arraycopy()(高性能),循环复制仅在需要特殊处理时使用。