返回

ArrayList 手撕:亲自动手打造你的专属动态数组

后端

众所周知,ArrayList 作为 Java 中的集合,是大家耳熟能详的数据结构。它以其灵活性和高效性著称,被广泛应用于各种场景中。然而,仅仅了解 ArrayList 的用法还不够,深入探究其底层实现,才能真正领悟其精髓。

今天,我们就将带着动手实践的精神,亲自手撕 ArrayList,打造属于我们自己的动态数组。

步骤 1:创建数组框架

ArrayList 的核心是一个数组,用于存储元素。我们首先创建一个私有数组 elementData 来存储我们的元素。

private Object[] elementData;

步骤 2:确定初始容量

ArrayList 的一个重要特性是它可以自动扩容。我们需要为 elementData 指定一个初始容量,也就是数组的初始大小。

public MyArrayList(int initialCapacity) {
    this.elementData = new Object[initialCapacity];
}

步骤 3:添加元素

添加元素是 ArrayList 的基本操作。我们使用 add 方法将元素添加到 elementData 数组中。如果数组已满,我们会调用 grow 方法扩容数组。

public void add(Object o) {
    if (size == elementData.length) {
        grow();
    }
    elementData[size++] = o;
}

步骤 4:扩容数组

elementData 数组已满时,我们需要扩容数组以容纳更多元素。grow 方法负责这一操作,它会创建一个新数组,并将旧数组中的元素复制到新数组中。

private void grow() {
    Object[] newElementData = new Object[elementData.length * 2];
    System.arraycopy(elementData, 0, newElementData, 0, elementData.length);
    elementData = newElementData;
}

步骤 5:移除元素

移除元素与添加元素类似。remove 方法根据索引从 elementData 数组中移除元素。

public void remove(int index) {
    if (index >= size) {
        throw new IndexOutOfBoundsException();
    }
    System.arraycopy(elementData, index + 1, elementData, index, size - index - 1);
    elementData[--size] = null;
}

步骤 6:获取元素

get 方法根据索引从 elementData 数组中获取元素。

public Object get(int index) {
    if (index >= size) {
        throw new IndexOutOfBoundsException();
    }
    return elementData[index];
}

步骤 7:其他操作

除了这些基本操作外,ArrayList 还提供了其他操作,如 size() (返回数组大小)、clear() (清除数组)、isEmpty() (检查数组是否为空)等。

总结

通过手撕 ArrayList,我们深入了解了动态数组的底层实现。它教会了我们如何创建、操作和维护一个动态数组,并为我们理解其他更复杂的集合类提供了坚实的基础。