返回

揭秘 ArrayList 的源码:深入解析动态数组的内部机制

后端

ArrayList:动态数组的深入剖析

探索 ArrayList 的内部机制

ArrayList 是 Java 集合框架中一种至关重要的数据结构,可用于存储和管理对象集合。它本质上是一个动态数组,可根据需要自动调整其大小。本篇文章将带你踏上深入探索 ArrayList 源码的旅程,揭示其幕后的秘密。

初始化:从无到有

ArrayList 的生命从一个容量为 0 的空数组开始。这块连续的内存空间是 ArrayList 存储元素的基础,为其未来的增长奠定了基础。

添加元素:动态扩展

添加元素是 ArrayList 的一项核心任务。当调用 add() 方法时,它首先检查其当前容量是否足以容纳新元素。如果空间不足,它将创建一个容量是当前容量两倍的新数组。然后,它将旧数组中的元素复制到新数组中,并添加新元素。

删除元素:巧妙挪移

删除元素与添加元素同样重要。当调用 remove() 方法时,ArrayList 会找到要删除的元素的索引。它巧妙地将该元素后面的所有元素向前移动一位,以填补空缺。最后,它将数组长度减 1,回收了被删除元素占据的空间。

访问元素:快捷高效

访问 ArrayList 中的元素就像在公园里散步一样简单。使用 get() 方法,你可以根据索引轻松检索元素。ArrayList 会对索引进行范围检查,确保你在有效范围内漫步。

深入理解 ArrayList 源码

public boolean add(E e) {
    modCount++;
    int minCapacity = size + 1;
    if (elementData.length < minCapacity)
        reallocate(minCapacity);
    elementData[size++] = e;
    return true;
}

public E remove(int index) {
    modCount++;
    rangeCheck(index);
    E oldValue = elementData(index);
    int numMoved = size - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    elementData[--size] = null; // Let gc do its work
    return oldValue;
}

public E get(int index) {
    rangeCheck(index);
    return elementData(index);
}

总结:动态数组的魔力

ArrayList 强大的秘密在于它是一种动态数组,可以根据需要扩展和缩小。它提供了一种高效的方式来存储和管理对象集合,使其成为 Java 程序员的宝贵工具。

常见问题解答

  1. ArrayList 和数组有什么区别?

    ArrayList 是一种动态数组,而数组是一个固定大小的数据结构。ArrayList 可以根据需要自动调整大小,而数组的大小是不可变的。

  2. ArrayList 的容量和大小有什么关系?

    ArrayList 的容量是其可以容纳的元素的最大数量,而大小是当前存储的元素数量。当大小达到容量时,ArrayList 会自动增加其容量。

  3. 如何避免 ArrayList 中的 ConcurrentModificationException?

    使用迭代器来遍历 ArrayList 可以避免 ConcurrentModificationException。如果在迭代过程中修改 ArrayList,则迭代器将抛出此异常。

  4. 如何提高 ArrayList 的性能?

    避免频繁添加和删除元素可以提高 ArrayList 的性能。此外,使用初始容量来指定 ArrayList 的初始大小可以减少重新分配操作的次数。

  5. 什么时候应该使用 LinkedList 而非 ArrayList?

    当需要频繁添加和删除元素时,LinkedList 比 ArrayList 更有优势。但是,对于随机访问操作,ArrayList 更为高效。