由于本文篇幅过长,为了方便大家阅读和收藏,特意将本文转成了一份PDF版的文档。
点击 下载 Java学习手册,pdf教程。
1. 集合概述
Java中集合主要分为三大类:
- List:有顺序,可重复。
- Set:无顺序,不可重复。
- Map:无顺序,不可重复。
其中List类集合中,最常用的就是ArrayList。
2. ArrayList概述
ArrayList拆分成两个单词分别是Array+List,Array表示数组,List表示列表。所以也表示了ArrayList的底层使用数组实现的。
传统数组在初始化时必须定义长度,且长度不能更改。
int[] arr1 = new int[10];
// 语法糖定义方式,初始化时按照初始成员确定长度
int[] arr2 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
ArrayList是动态数组,初始化时可以不定义长度,在JVM判断ArrayList容量不足时,会自动扩容数组。
ArrayList<Integer> arrayList = new ArrayList<>();
3. 数组特性
ArrayList底层使用数组实现,所以ArrayList具备数组的所有特性。在研究ArrayList之前,必须了解数组在JVM中的底层实现原理。
数组的特性:
- 数组元素必须是同一种数据类型。
- 数组元素在内存中是连续存储的。
- 数组元素的随机访问效率特别高,可以实现常量级的随机访问,时间复杂度为O(1)。
由第一个特性可知,数组中每一个元素的占用空间都是一样的。第一个特性结合第二个特性可以得出第三个特性。

问题:为什么数组查询的效率比链表高?
一个数组对象在创建时,JVM会给其分配一个基地址。在查询该数组中第 K+1 个元素时,只需要 [ 基地址 + K * 元素大小 ] 可以直接得到到第 K+1元素的地址,从而可以访问该元素中的数据。该过程只进行了 1 次寻址的操作。
在查询链表中第 K+1 个元素时,一般情况下,会从链表的头节点依次通过next指针指向找到第 K+1个元素。该操作需要进行 K 次寻址的操作。
4. ArrayList源码分析
4.1 继承结构

4.2 类结构
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
// 序列化处理过程中验证传输类和本地类版本是否一致
private static final long serialVersionUID = 8683452581122892189L;
// 数组默认初始化容量
private static final int DEFAULT_CAPACITY = 10;
// 数组中当前包含的元素个数
private int size;
// 数据存储的数组
transient Object[] elementData;
// 用于空实例的共享空数组实例
private static final Object[] EMPTY_ELEMENTDATA = {};
// 用于默认大小的空实例的共享空数组实例
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
// 集合版本号,每次对集合进行增加和删除元素都会+1
protected transient int modCount = 0;
...
}
- ArrayList类继承了AbstractList抽象类和实现了List接口,表示ArrayList实例具备add,remove,set,get等最基本的位置操作。
- ArrayList类实现了RandomAccess标记接口,标记ArrayList实例具备快速随机访问的能力。
- ArrayList类实现了Cloneable标记接口,标记ArrayList实例可以被克隆。
- ArrayList类实现了Serializable标记接口,标记ArrayList实例支持序列化,可以在网络中传输。
- elementData成员变量被transient关键字修饰,表示elementData在ArrayList实例序列化处理的过程中会被忽略。因为在实际使用场景中,elementData可能不是满的,只有数据部分才需要序列化。所以ArrayList采用了重写writeObject方法和readObject方法来自定义elementData的序列化处理过程。
- modCount成员变量的作用是用来触发fail-fast机制,下文会具体介绍。
4.3 初始化
4.3.1 无参构造器
public ArrayList()

本文深入剖析了ArrayList,从集合概述、ArrayList的数组特性、源码分析到面试题,详细讲解了ArrayList的构造、添加、移除、遍历等操作,并探讨了其扩容策略、fail-fast机制和迭代器的实现。适合Java开发者巩固ArrayList知识和面试准备。

2万+

被折叠的 条评论
为什么被折叠?



