本文目录导读:

我来为您详细介绍Java数组扩容的几种实现方法及案例。
基础概念
Java数组一旦创建,长度不可改变,扩容实际上是创建一个新数组,将原数组内容复制到新数组中。
实现方式
手动实现数组扩容
public class ArrayExpandDemo1 {
// 手动扩容方法
public static int[] expandArray(int[] original, int newLength) {
// 创建新数组
int[] newArray = new int[newLength];
// 复制原数组元素
for (int i = 0; i < original.length; i++) {
newArray[i] = original[i];
}
return newArray;
}
public static void main(String[] args) {
// 原数组
int[] arr = {1, 2, 3, 4, 5};
System.out.println("原数组: " + Arrays.toString(arr));
System.out.println("原数组长度: " + arr.length);
// 扩容到10个元素
int[] expandedArr = expandArray(arr, 10);
System.out.println("扩容后数组: " + Arrays.toString(expandedArr));
System.out.println("扩容后长度: " + expandedArr.length);
// 添加新元素
expandedArr[5] = 6;
expandedArr[6] = 7;
System.out.println("添加元素后: " + Arrays.toString(expandedArr));
}
}
使用System.arraycopy()
public class ArrayExpandDemo2 {
// 使用System.arraycopy实现扩容
public static String[] expandArray(String[] original, int newLength) {
String[] newArray = new String[newLength];
// 参数说明:
// 源数组,源起始位置,目标数组,目标起始位置,复制长度
System.arraycopy(original, 0, newArray, 0, original.length);
return newArray;
}
public static void main(String[] args) {
String[] names = {"张三", "李四", "王五"};
System.out.println("原数组: " + Arrays.toString(names));
// 扩容到5个元素
names = expandArray(names, 5);
System.out.println("扩容后: " + Arrays.toString(names));
// 添加新元素
names[3] = "赵六";
names[4] = "钱七";
System.out.println("添加后: " + Arrays.toString(names));
}
}
使用Arrays.copyOf()
public class ArrayExpandDemo3 {
public static void main(String[] args) {
// 原数组
double[] prices = {99.9, 199.5, 299.0};
System.out.println("原数组: " + Arrays.toString(prices));
// 方式1:直接扩容
double[] expanded1 = Arrays.copyOf(prices, 6);
System.out.println("扩容后: " + Arrays.toString(expanded1));
// 方式2:缩小数组(截取前2个元素)
double[] trimmed = Arrays.copyOf(prices, 2);
System.out.println("截取后: " + Arrays.toString(trimmed));
}
}
动态扩容工具类
public class DynamicArray<T> {
private Object[] data;
private int size;
private static final int DEFAULT_CAPACITY = 10;
public DynamicArray() {
data = new Object[DEFAULT_CAPACITY];
size = 0;
}
public DynamicArray(int initialCapacity) {
if (initialCapacity < 0) {
throw new IllegalArgumentException("容量不能为负数: " + initialCapacity);
}
data = new Object[initialCapacity];
size = 0;
}
// 添加元素(自动扩容)
public void add(T element) {
ensureCapacity(size + 1);
data[size++] = element;
}
// 确保容量
private void ensureCapacity(int minCapacity) {
if (minCapacity > data.length) {
// 扩容策略:1.5倍
int newCapacity = data.length + (data.length >> 1);
// 如果新容量仍不够,使用所需最小容量
if (newCapacity < minCapacity) {
newCapacity = minCapacity;
}
data = Arrays.copyOf(data, newCapacity);
System.out.println("数组已扩容到: " + newCapacity);
}
}
// 获取元素
@SuppressWarnings("unchecked")
public T get(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException("索引越界: " + index);
}
return (T) data[index];
}
// 获取大小
public int size() {
return size;
}
// 获取容量
public int capacity() {
return data.length;
}
// 打印数组
public void printArray() {
System.out.print("数组内容: [");
for (int i = 0; i < size; i++) {
System.out.print(data[i]);
if (i < size - 1) {
System.out.print(", ");
}
}
System.out.println("]");
}
}
实际应用案例 - 学生管理系统
public class StudentManager {
private String[] students;
private int count;
public StudentManager() {
students = new String[3]; // 初始容量3
count = 0;
}
// 添加学生
public void addStudent(String name) {
// 检查是否需要扩容
if (count >= students.length) {
// 扩容为原数组1.5倍
int newCapacity = students.length + (students.length >> 1);
students = Arrays.copyOf(students, newCapacity);
System.out.println("数组已扩容到: " + newCapacity);
}
students[count++] = name;
System.out.println("添加学生: " + name);
}
// 显示所有学生
public void showStudents() {
System.out.println("\n当前学生列表:");
for (int i = 0; i < count; i++) {
System.out.println((i + 1) + ". " + students[i]);
}
System.out.println("当前容量: " + students.length + ", 已使用: " + count + "\n");
}
public static void main(String[] args) {
StudentManager manager = new StudentManager();
// 添加学生,观察自动扩容
manager.addStudent("张三");
manager.showStudents();
manager.addStudent("李四");
manager.addStudent("王五");
manager.showStudents();
manager.addStudent("赵六");
manager.addStudent("钱七");
manager.showStudents();
}
}
扩容策略对比
| 方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 手动实现 | 理解原理 | 代码繁琐 | 学习理解 |
| System.arraycopy | 高效,本地方法 | 语法不友好 | 高并发场景 |
| Arrays.copyOf | 简洁优雅 | 内部也是arraycopy | 大多数场景 |
| 动态数组类 | 自动管理容量 | 需要封装类 | 业务开发 |
扩容策略建议
// 常见扩容策略
public class ArrayExpandStrategy {
// 策略1:固定增量
public static int[] expandFixed(int[] arr) {
return Arrays.copyOf(arr, arr.length + 10);
}
// 策略2:翻倍扩容(ArrayList策略)
public static int[] expandDouble(int[] arr) {
return Arrays.copyOf(arr, arr.length * 2);
}
// 策略3:1.5倍扩容(HashMap策略)
public static int[] expandHalf(int[] arr) {
return Arrays.copyOf(arr, arr.length + (arr.length >> 1));
}
// 策略4:按需扩容
public static int[] expandNeeded(int[] arr, int needed) {
if (needed > arr.length) {
int newCapacity = Math.max(arr.length * 2, needed);
return Arrays.copyOf(arr, newCapacity);
}
return arr;
}
}
注意事项
- 避免频繁扩容:每次扩容都会创建新数组,影响性能
- 合理设置初始容量:如果知道大概数据量,预留足够空间
- 缩容考虑:删除元素后可能不需要缩容,避免不必要的资源消耗
- 线程安全:多线程环境下需要考虑同步机制
Java数组扩容最推荐使用Arrays.copyOf()方法,它内部调用了System.arraycopy(),既简洁又高效,在实际开发中,可以直接使用ArrayList或Vector等集合类,它们内部已经实现了自动扩容机制。