注:既然是源码,为什么要这样设计类,有这样的继承关系。这就要说到设计模式的问题了。所以我们要了解常用的设计模式,才能更深刻的去理解这个类。
文章目录
-
- 简介
-
继承关系图
-
成员变量
-
构造方法
-
内部类
-
核心方法
-
- add()方法(有四个)
-
对数组的容量进行调整
-
大数据插入问题
-
remove()方法
-
get()方法
-
set()方法
-
indexOf()方法
-
contains()方法
-
toArray()方法
-
System.arraycopy()和 Arrays.copyOf()方法
-
- System.arraycopy()方法
-
Arrays.copyOf()方法
-
两者联系与区别
ArrayList 是 Java 集合框架中 List 接口的一个实现类。底层是数组,相当于动态数组。与 Java 中的数组相比,它的容量能动态增长。
ArrayList
是Vector
的翻版,区别在于ArrayList
是线程不安全的,而Vector
则是线程安全的。但是Vector
是一个较老的集合,具有很多缺点,不建议使用,这里我们就不对其进行分析了。
ArrayList 可以说是我们使用最多的 List 集合,它有以下特点:
-
它是基于数组实现的List类
-
可以动态地调整容量
-
有序的(元素输出顺序与输入顺序一致)
-
元素可以为 null
-
不同步,非线程安全,效率高
-
查询快,增删慢
-
占用空间更小,对比 LinkedList,不用占用额外空间维护链表结构
ArrayList 为什么有这些优点呢?我们通过源码来分析分析。在阅读源码前先来看看ArrayList继承关系。
可以看到,ArrayList
是AbstractList
的子类,同时实现了List
接口。除此之外,它还实现了三个标识型接口,这几个接口都没有任何方法,仅作为标识表示实现类具备某项功能。RandomAccess
表示实现类支持快速随机访问,Cloneable
表示实现类支持克隆,具体表现为重写了clone
方法,java.io.Serializable
则表示支持序列化,如果需要对此过程自定义,可以重写writeObject
与readObject
方法。
// 序列号
private static final long serialVersionUID = 8683452581122892189L;
// 数组初始容量为 10
private static final int DEFAULT_CAPACITY = 10;
// 空对象数组
private static final Object[] EMPTY_ELEMENTDATA = {};
// 缺省空对象数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
// 底层数据结构,数组
transient Object[] elementData;
// 数组元素个数,默认为0
private int size;
// 最大数组容量
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
//默认构造方法,初始为空数组。
//只有插入一条数据后才会扩展为10,而实际上默认是空的
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
//根据指定容量创建对象数组
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
//创建initialCapacity大小的数组
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
//创建空数组
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
/**
- 构造一个包含指定集合的元素的列表,按照它们由集合的迭代器返回的顺序。
*/
public ArrayList(Collection<? extends E> c) {
//转换最主要的是toArray(),这在