ArrayList 模拟手动数组扩容

📅 2026/6/28 23:12:15
ArrayList 模拟手动数组扩容
用 ArrayList 模拟手动数组扩容底层原理复刻思路说明ArrayList 底层是Object[]核心扩容逻辑初始空数组添加元素时判断容量是否足够不够则新建1.5倍容量的新数组通过数组拷贝System.arraycopy把旧数据迁移到新数组替换底层数组引用下面自己手写简易动态数组模仿 ArrayList 扩容逻辑不直接调用原生 ArrayList展示扩容底层实现。完整代码publicclassMyArrayListE{// 底层存储数组privateObject[]elementData;// 当前元素个数privateintsize;// 默认初始容量privatestaticfinalintDEFAULT_CAPACITY10;// 空数组常量privatestaticfinalObject[]EMPTY_ELEMENTDATA{};// 无参构造初始为空数组publicMyArrayList(){elementDataEMPTY_ELEMENTDATA;}// 添加元素核心扩容逻辑在这里publicbooleanadd(Ee){// 1. 判断是否需要扩容ensureCapacityInternal(size1);// 2. 存入元素elementData[size]e;returntrue;}// 确保容量足够不足则扩容privatevoidensureCapacityInternal(intminCapacity){// 如果是空数组第一次添加直接扩容到默认容量10if(elementDataEMPTY_ELEMENTDATA){minCapacityMath.max(DEFAULT_CAPACITY,minCapacity);}// 当前数组容量intoldCapacityelementData.length;// 需要扩容if(minCapacityoldCapacity){grow(minCapacity);}}// 真正扩容方法新容量 旧容量 * 1.5privatevoidgrow(intminCapacity){intoldCapacityelementData.length;// 扩容1.5倍intnewCapacityoldCapacity(oldCapacity1);// 若1.5倍还是不够直接使用需要的最小容量if(newCapacity-minCapacity0){newCapacityminCapacity;}// 数组拷贝生成新数组elementDatacopyOf(elementData,newCapacity);}// 模拟 Arrays.copyOf 数组复制privateObject[]copyOf(Object[]oldArr,intnewLen){Object[]newArrnewObject[newLen];// 复制旧数组所有元素到新数组System.arraycopy(oldArr,0,newArr,0,oldArr.length);returnnewArr;}// 根据下标获取元素SuppressWarnings(unchecked)publicEget(intindex){checkIndex(index);return(E)elementData[index];}// 校验下标privatevoidcheckIndex(intindex){if(index0||indexsize){thrownewIndexOutOfBoundsException(下标越界index);}}// 获取当前元素数量publicintsize(){returnsize;}// 打印所有元素publicvoidprintAll(){for(inti0;isize;i){System.out.print(elementData[i] );}System.out.println();}// 测试主方法publicstaticvoidmain(String[]args){MyArrayListIntegerlistnewMyArrayList();// 添加15个元素触发扩容初始10加到第11个时扩容到15for(inti1;i15;i){list.add(i);System.out.println(添加第i个元素当前元素总数list.size());}System.out.print(集合所有元素);list.printAll();System.out.println(下标5的元素list.get(5));}}运行结果说明前10个元素底层数组长度10不扩容添加第11个元素时minCapacity11旧容量10不足触发扩容新容量 10 10/2 15创建长度15的新数组复制旧数据最多存15个元素不会再次扩容直到超过15个才会再次1.5倍扩容如果要求直接使用原生 ArrayList 演示扩容现象原生 ArrayList 无法直接获取底层数组长度可通过反射查看容量代码importjava.util.ArrayList;importjava.lang.reflect.Field;publicclassArrayListExpandDemo{publicstaticvoidmain(String[]args)throwsException{ArrayListIntegerlistnewArrayList();// 反射获取底层数组 elementDataFieldfieldArrayList.class.getDeclaredField(elementData);field.setAccessible(true);for(inti1;i12;i){list.add(i);Object[]arr(Object[])field.get(list);System.out.println(添加i数组容量arr.length元素个数sizelist.size());}}}输出添加1数组容量10元素个数size1 ... 添加10数组容量10元素个数size10 添加11数组容量15元素个数size11 添加12数组容量15元素个数size12直观看到存满10个后第11个元素触发1.5倍扩容到15。核心扩容关键点总结扩容倍数oldCapacity oldCapacity 1 原容量 * 1.5扩容本质新建更大数组 System.arraycopy拷贝数据空集合第一次add直接分配容量10若1.5倍容量仍不够存放当前数据直接使用需要的最小容量