一文带你进行ArrayList 源码分析

举报
wljslmz 发表于 2023/05/30 23:48:25 2023/05/30
【摘要】 ArrayList 是 Java 中常用的一种 List 容器,其内部使用数组实现。该容器的主要功能就是用于存储和操作各种数据类型的元素。在本文中,我们将对 ArrayList 的源码进行详细分析,以帮助读者更好地了解其内部实现机制。 常用方法在开始分析 ArrayList 的源码之前,我们先来简要介绍一下该容器的常用方法。 add 方法该方法用于向 ArrayList 尾部添加元素,其函数...

ArrayList 是 Java 中常用的一种 List 容器,其内部使用数组实现。该容器的主要功能就是用于存储和操作各种数据类型的元素。在本文中,我们将对 ArrayList 的源码进行详细分析,以帮助读者更好地了解其内部实现机制。

常用方法

在开始分析 ArrayList 的源码之前,我们先来简要介绍一下该容器的常用方法。

add 方法

该方法用于向 ArrayList 尾部添加元素,其函数签名如下:

public boolean add(E e)

其中,E 表示该容器中存放的元素类型。该方法会返回一个布尔值,表示元素是否添加成功。

get 方法

该方法用于获取指定位置处的元素,其函数签名如下:

public E get(int index)

其中,index 表示要获取的元素在 ArrayList 中的下标,E 表示元素的类型。该方法会返回获取到的元素。

remove 方法

该方法用于移除指定位置处的元素,其函数签名如下:

public E remove(int index)

其中,index 表示要移除的元素在 ArrayList 中的下标,E 表示元素的类型。该方法会返回被移除的元素。

size 方法

该方法用于获取 ArrayList 中的元素数量,其函数签名如下:

public int size()

该方法会返回 ArrayList 中元素的个数,即数组的长度。

构造函数

在分析源码之前,我们先来看一下 ArrayList 的构造函数。ArrayList 有 3 种不同的构造函数,分别如下:

public ArrayList()
public ArrayList(Collection<? extends E> c)
public ArrayList(int initialCapacity)

第一种构造函数用于创建一个空的 ArrayList,第二种构造函数用于创建一个包含指定 Collection 中所有元素的 ArrayList,第三种构造函数用于创建一个指定初始容量的 ArrayList。

源码分析

接下来,我们将依次分析 ArrayList 中的各个方法及其实现机制。

成员变量

ArrayList 中包含了如下成员变量:

transient Object[] elementData;
private int size;
private static final int DEFAULT_CAPACITY = 10;

其中,elementData 表示存储元素的数组,size 表示 ArrayList 中元素的数量,DEFAULT_CAPACITY 表示该容器默认的初始容量。

add 方法实现

ArrayList 的 add 方法的实现如下:

public boolean add(E e) {
    modCount++;
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}

add 方法首先会将 modCount(修改计数器)加 1,然后会调用 ensureCapacityInternal 方法保证 ArrayList 中的数组可以容纳新的元素。然后将新的元素添加到数组的末尾,并将 size (元素数量)加 1。最后,将 true 返回表示元素添加成功。

get 方法实现

ArrayList 的 get 方法的实现如下:

public E get(int index) {
    rangeCheck(index);

    return elementData(index);
}

get 方法首先会调用 rangeCheck 方法,确保传入的下标是合法的。如果下标不合法,rangeCheck 方法会抛出一个 IndexOutOfBoundsException 异常。如果下标合法,get 方法则会调用 elementData(index) 方法获取对应下标位置的元素。

elementData(index) 方法的实现如下:

E elementData(int index) {
    return (E) elementData[index];
}

该方法直接返回数组中对应下标的元素。

remove 方法实现

ArrayList 的 remove 方法的实现如下:

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; // clear to let GC do its work

    return oldValue;
}

remove 方法首先会将 modCount(修改计数器)加 1,并调用 rangeCheck 方法,确保传入的下标是合法的。如果下标不合法,rangeCheck 方法会抛出一个 IndexOutOfBoundsException 异常。

如果下标合法,则会获取对应下标位置的元素,并将 size 减 1。然后,使用 System.arraycopy 方法将下标为 index+1 开始的元素向前移动一个位置(相当于删除了下标为 index 的元素)。清空原数组的最后一个元素,并将被删除的元素返回。

private 方法

除了上述三个常用方法外,ArrayList 中还包含了很多 private 方法,这些方法主要用于实现 ArrayList 内部使用的各种机制。其中比较重要的方法如下:

  • ensureCapacityInternal 方法:该方法用于确保 ArrayList 中的数组可以容纳新的元素。在需要添加新元素时,先调用该方法,如果当前数组容量不足,就会扩容。
  • grow 方法:该方法用于对 ArrayList 进行扩容。当 elementData 数组已满时,就会调用该方法进行扩容操作。
  • rangeCheck 方法:该方法用于判断传入的下标是否合法。如果下标不合法,该方法会抛出一个 IndexOutOfBoundsException 异常。
  • trimToSize 方法:该方法用于缩小 elementData 数组的容量。调用该方法后,elementData 数组的长度会被设置为当前 elementData 中包含的元素数量。
  • toArray 方法:该方法用于将包含在 ArrayList 中的元素存储到一个数组中。
  • clone 方法:该方法用于创建并返回 ArrayList 的副本。

总结

通过以上分析,我们可以看出,ArrayList 是一种使用数组实现的 List 容器。它提供了丰富的方法,使得用户能够方便地对其中的元素进行增、删、查等操作。ArrayList 内部使用了很多机制来优化其性能,如扩容、压缩等。如果您对 ArrayList 的实现机制感兴趣,建议花更多时间深入研究其源代码。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。