一文带你进行ArrayList 源码分析

简介: 一文带你进行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 的实现机制感兴趣,建议花更多时间深入研究其源代码。

目录
相关文章
|
6月前
ArrayList源码解读
ArrayList源码解读
23 1
|
6月前
|
存储 算法
HashMap源码分析
HashMap源码分析
|
存储 Java 索引
ArrayList源码分析
ArrayList源码分析
|
存储 Java
HashMap 的 源码分析
HashMap 的 源码分析
87 0
|
存储 Java 程序员
ArrayList 的底层原理
ArrayList 是 Java 中常用的动态数组实现,它的底层是基于数组实现的。当创建一个 ArrayList 对象时,实际上是创建了一个 Object 类型的数组,初始容量为 10。当添加元素时,如果数组已满,ArrayList 会自动扩容,它会创建一个新的数组,并将原数组中的元素复制到新数组中。
941 0
ArrayList 的底层原理
|
存储 安全 Java
源码剖析之ArrayList
ArrayList 是一个数组队列,相当于 动态数组。与Java中的数组相比,它的容量能动态增长。它继承于AbstractList,实现了List, RandomAccess, Cloneable, java.io.Serializable这些接口。
89 0
ArrayList与LinkedList获取指定元素对比(源码分析)
ArrayList与LinkedList获取指定元素对比(源码分析)
76 0
|
存储 Java
LinkedList源码分析
Java中List是一个必须要掌握的基础知识,List是一个接口,实现List接口的基础类有很多,其中最具有代表性的两个:ArrayList和LinkedList。
232 0
LinkedList源码分析
|
存储 索引
ArrayList与LinkedList区别源码分析
1、ArrayList是基于数组,LinkedList是基于链表 2、基于数组的ArrayList对于根据索引值查找比较高效;基于链表的LinkedList对于增加、删除操作比较高效 3、剖析CRUD:
223 0
|
存储 缓存 Java
ArrayList源码浅析
Java中List是一个必须要掌握的基础知识,List是一个接口,实现List接口的基础类有很多,其中最具有代表性的两个:ArrayList和LinkedList。
168 0