本文目录导读:

我来为您详细介绍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等集合类,它们内部已经实现了自动扩容机制。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播