java原生数组长度固定,动态扩容需手动创建新数组、复制数据并更新引用;add()前需判断size+1>length,扩容倍数推荐1.5倍(oldcapacity+(oldcapacity>>1)),首次扩容默认10,复制仅限前size个元素。

Java 原生数组(如 int[]、String[])长度固定,无法直接扩容。要实现“动态扩容”,本质是**手动封装一个数组容器,通过创建新数组 + 复制数据 + 更新引用**来模拟可变行为。关键不是改变原数组,而是用更大的数组替代它。
扩容触发时机必须精准:size + 1 > array.length
不能等 size == array.length 才扩容——此时已无空位,下一次添加必然越界。正确逻辑是在插入前判断是否还有空间:
- 每次调用
add()时,先检查if (size + 1 > elementData.length) - 满足条件则立即执行
resize(),再赋值elementData[size++] = e -
size表示当前有效元素个数,elementData.length是物理容量,二者语义严格分离
新容量计算推荐 1.5 倍,避免极端策略
盲目翻倍(×2)浪费内存,只加 1(+1)导致频繁复制。工业级方案是位运算实现的 1.5 倍增长:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
int newCapacity = oldCapacity + (oldCapacity >> 1);(等价于oldCapacity * 1.5) - 首次扩容有兜底:若旧容量为 0(如空构造),直接设为默认值 10
- 还要防溢出:
if (newCapacity - minCapacity (比如批量 add 20 个,就直接扩到 20) - 上限保护:
if (newCapacity > Integer.MAX_VALUE - 8) throw new OutOfMemoryError();
复制数据必须按 size 截断,不能遍历整个新数组
扩容后新数组更长,但只有前 size 个位置有真实数据。若遍历全部长度,会读到 0、null 等默认值,引发空指针或业务误判:
- ✅ 正确复制:
elementData = Arrays.copyOf(elementData, newCapacity); - ✅ 或底层写法:
System.arraycopy(oldArray, 0, newArray, 0, size); - ❌ 错误做法:用
for (int i = 0; i 遍历打印或序列化
缩容需设阈值,防止反复扩缩抖动
删除大量元素后若不缩容,内存持续占用;但删一个就缩一次,又会抖动。合理做法是设置填充率下限:
- 在
remove()后检查:if (size > 0 && size - 触发缩容时,新容量 =
elementData.length / 2,但不低于最小保护值(如 8 或初始容量) - 缩容同样用
Arrays.copyOf(elementData, newCapacity)截取前newCapacity个元素 -
clear()只需置size = 0,无需立即缩容或清空数组内容
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










