You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 15:17:27