返回

深度剖析 ArrayList 源码,探寻集合框架的奥秘

后端

概述

在 Java 集合框架中,ArrayList 扮演着举足轻重的角色。它是一款动态数组,具有可变大小的特性,能随着元素的增减而自动调整自身容量。ArrayList 的设计精妙、性能卓越,是程序员们处理有序数据结构的利器。为了更深入地理解 ArrayList 的运作机制,我们不妨对它的源码进行一番细致的剖析。

源码分析

1. 数据结构

ArrayList 的数据结构就是一个简单的数组,其中每个元素都是一个对象引用。为了提高内存利用率,ArrayList 会在数组中预留一定的空间,以便在添加新元素时不必重新分配内存。

private Object[] elementData; // 数组,存储元素
private int size; // 元素个数

2. 构造函数

ArrayList 提供了多种构造函数,允许用户指定初始容量、拷贝已有集合等。

public ArrayList() {
    this(10); // 默认初始容量为 10
}

public ArrayList(int initialCapacity) {
    if (initialCapacity < 0) {
        throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);
    }
    elementData = new Object[initialCapacity];
}

public ArrayList(Collection<? extends E> c) {
    elementData = c.toArray();
    size = elementData.length;
}

3. 核心方法

  • add(): 添加一个元素到 ArrayList 的末尾。
public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // 确保容量足够
    elementData[size++] = e;
    return true;
}
  • get(): 获取指定索引处的元素。
public E get(int index) {
    rangeCheck(index);
    return elementData[index];
}
  • remove(): 移除指定索引处的元素。
public E remove(int index) {
    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;
}

4. 内部实现

ArrayList 的内部实现涉及一些巧妙的技巧和优化。例如,当 ArrayList 容量不够时,它会自动扩容,以避免频繁的内存分配和拷贝操作。

private void ensureCapacityInternal(int minCapacity) {
    if (elementData == null) {
        elementData = new Object[DEFAULT_CAPACITY];
    } else if (minCapacity - elementData.length > 0) {
        grow(minCapacity);
    }
}

private void grow(int minCapacity) {
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0) {
        newCapacity = minCapacity;
    }
    elementData = Arrays.copyOf(elementData, newCapacity);
}

应用场景

ArrayList 广泛应用于各种场景,包括但不限于:

  • 存储有序数据,例如用户列表、购物车中的商品列表等。
  • 作为其他数据结构的基础,例如栈和队列。
  • 在算法中存储中间结果,例如排序算法中的临时数组。

优势与劣势

优势:

  • 随机访问性能优异。
  • 扩容操作高效。
  • 支持快速随机访问和插入删除操作。
  • 使用简单方便。

劣势:

  • 内存开销较大。
  • 对于频繁的插入删除操作,可能会导致性能下降。

结语

ArrayList 是 Java 集合框架中不可或缺的一部分,它简单易用,性能卓越,是程序员们处理有序数据结构的得力助手。通过对 ArrayList 源码的深入分析,我们对它的结构、操作方法和内部实现有了更深刻的理解。希望本文能够帮助您更熟练地使用 ArrayList,并在您的编程实践中发挥更大的作用。