简介#

  • ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存。
  • ArrayList不是线程安全的,只能用在单线程环境下,多线程环境下可以考虑用Collections.synchronizedList(List l)函数返回一个线程安全的ArrayList类,也可以使用concurrent并发包下的CopyOnWriteArrayList类。
  • ArrayList实现了Serializable接口,因此它支持序列化,能够通过序列化传输,实现了RandomAccess接口,支持快速随机访问,实际上就是通过下标序号进行快速访问,实现了Cloneable接口,能被克隆。

存储结构#

Copy
// 当前数据对象存放地方,当前对象不参与序列化 // 这个关键字最主要的作用就是当序列化时,被transient修饰的内容将不会被序列化 transient Object[] elementData;
  • Object类型数组。

    数据域#

Copy
// 序列化ID private static final long serialVersionUID = 8683452581122892189L; // 默认初始容量 private static final int DEFAULT_CAPACITY = 10; // 一个空数组,方便使用,主要用于带参构造函数初始化和读取序列化对象等。 private static final Object[] EMPTY_ELEMENTDATA = {}; /** * 和官方文档写的一样,DEFAULTCAPACITY_EMPTY_ELEMENTDATA 和EMPTY_ELEMENTDATA 的区别 * 仅仅是为了区别用户带参为0的构造和默认构造的惰性初始模式对象。 * 当用户带参为0的构造,第一次add时,数组容量grow到1。 * 当用户使用默认构造时,第一次add时,容量直接grow到DEFAULT_CAPACITY(10)。 */ private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; // 当前数据对象存放地方,当前对象不参与序列化 // 这个关键字最主要的作用就是当序列化时,被transient修饰的内容将不会被序列化 transient Object[] elementData; // non-private to simplify nested class access // 当前数组中元素的个数 private int size; // 数组最大可分配容量 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; // 集合数组修改次数的标识(由AbstractList继承下来)(fail-fast机制) protected transient int modCount = 0;
  • ArrayList的无参构造函数。初始化的时候并没有真正的创建10个空间,这是惰性初始模式对象。
  • DEFAULTCAPACITY_EMPTY_ELEMENTDATA 和EMPTY_ELEMENTDATA 的区别仅仅是为了区别用户带参为0的构造和默认构造的惰性初始模式对象。
  • modCount用来记录ArrayList结构发生变化的次数。用于Fail-Fast机制

构造函数#

Copy
public ArrayList() { // 只有这个地方会引用DEFAULTCAPACITY_EMPTY_ELEMENTDATA this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { // 使用 EMPTY_ELEMENTDATA,在其他的多个地方可能会引用EMPTY_ELEMENTDATA this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } } public ArrayList(Collection<? extends E> c) {