如何在Java中模拟ArrayList?动态扩容实现求助
解决Java模拟ArrayList的动态扩容问题
核心问题分析
你当前的代码存在两个关键问题:
resizeArray方法是空实现,没有真正完成数组扩容逻辑- 通过遍历找
null判断数组是否已满的方式效率低,还会在元素包含null时出错
解决方案步骤
1. 优化类的基础结构
添加size字段跟踪实际元素数量,这是Java ArrayList的标准实现方式,避免遍历数组的低效操作:
private Object[] elements; private int size; // 新增:记录实际存储的元素个数
修正构造方法,Java引用类型数组默认元素就是null,不需要循环赋值:
public StudentArrayList() { elements = new Object[2]; size = 0; } public StudentArrayList(int capacity) { if (capacity < 0) { throw new IllegalArgumentException("容量不能为负数"); } elements = new Object[capacity]; size = 0; }
2. 实现真正的扩容方法
扩容的核心逻辑是创建新的更大的数组,将原数组的有效元素复制到新数组,然后替换原数组:
private void resizeArray(int newCapacity) { // 创建新的容量更大的数组 Object[] newElements = new Object[newCapacity]; // 复制原数组中的有效元素(仅前size个) for (int i = 0; i < size; i++) { newElements[i] = elements[i]; } // 替换原数组 elements = newElements; }
通常ArrayList会把扩容倍数设为原容量的1.5倍(平衡空间和效率),你也可以根据需求改用固定增量。
3. 修正add方法逻辑
利用size字段直接定位插入位置,先判断是否需要扩容:
public void add(E e) { // 检查是否需要扩容:如果实际元素个数等于数组容量,就扩容 if (size == elements.length) { // 扩容为原容量的1.5倍,也可以改成你想要的固定值比如elements.length + 10 resizeArray(elements.length * 2); } // 把元素放到size对应的位置,然后size自增 elements[size] = e; size++; }
4. 修正toString方法
基于size遍历,避免遍历整个数组的无效位置,同时用StringBuilder提升拼接效率:
@Override public String toString() { StringBuilder stringOfElements = new StringBuilder("["); for (int i = 0; i < size; i++) { if (i != 0) { stringOfElements.append(", "); } stringOfElements.append(elements[i]); } stringOfElements.append("]"); return stringOfElements.toString(); }
修改后的完整代码
实现类
package IncreaseArraySize; public class StudentArrayList<E> { private Object[] elements; private int size; public StudentArrayList() { elements = new Object[2]; size = 0; } public StudentArrayList(int capacity) { if (capacity < 0) { throw new IllegalArgumentException("容量不能为负数"); } elements = new Object[capacity]; size = 0; } public void add(E e) { if (size == elements.length) { resizeArray(elements.length * 2); } elements[size] = e; size++; } private void resizeArray(int newCapacity) { Object[] newElements = new Object[newCapacity]; for (int i = 0; i < size; i++) { newElements[i] = elements[i]; } elements = newElements; } @Override public String toString() { StringBuilder stringOfElements = new StringBuilder("["); for (int i = 0; i < size; i++) { if (i != 0) { stringOfElements.append(", "); } stringOfElements.append(elements[i]); } stringOfElements.append("]"); return stringOfElements.toString(); } }
测试类
package IncreaseArraySize; public class testMyArrayList { public static void main(String[] args) { StudentArrayList<String> myArrayList = new StudentArrayList<>(2); System.out.println("Initial list of elements = " + myArrayList.toString()); myArrayList.add("this works fine"); myArrayList.add("this works fine too"); System.out.println("List of elements = " + myArrayList.toString()); myArrayList.add("This doesn't work"); System.out.println("Array was resized: list of elements= " + myArrayList.toString()); } }
测试结果
运行测试类后,输出会是:
Initial list of elements = [] List of elements = [this works fine, this works fine too] Array was resized: list of elements= [this works fine, this works fine too, This doesn't work]
内容的提问来源于stack exchange,提问作者Gilson dos Reis
相关产品推荐
相关产品推荐

