前言
本文环境 jdk 1.8
ArrayList
这个集合容器我相信是 Java 工程师在工作当中用的最常用的集合了。但用的多并不代表就很了解它,对它的了解程度应该只有这样:ArrayList
和 LinkedList
有什么区别。
那本文就来分析一下ArrayList
的源码,深入理解ArrayList
的实现原理。让你回答面试题的时候,让面试官觉得你不同于那些妖艳**。
定义
public class ArrayList<E> extends AbstractList<E> implements
List<E>, RandomAccess, Cloneable, java.io.Serializable
复制代码
ArrayList
本身直接继承AbstractList
,实现List
、 RandomAccess
、 Cloneable
、 Serializable
接口。
- RandomAccess:标记接口,标注该类可随机访问
- Cloneable:可以克隆拷贝
- Serializable:可序列化
构造函数
在使用 ArrayList
的时候,都是用使用构造函数进行初始化的。分别来介绍一下它的几个构造函数。
无参构造
- 使用
ArrayList<String> list = new ArrayList<>();
复制代码
- 源码
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
复制代码
elementData
和 DEFAULTCAPACITY_EMPTY_ELEMENTDATA
都是成员变量,一起来看看:
// Object 数组,用来存放元素
transient Object[] elementData;
// 空的 Object数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
复制代码
看到上述无参构造方法的源码,可以知道当我们 new 一个无参 ArrayList
的时候,内部使用了一个空的数组赋值给了用于保存数据的数组。
ArrayList(int initialCapacity)
- 使用
ArrayList<String> list = new ArrayList<>(4);
复制代码
- 源码
public ArrayList(int initialCapacity) {
if(initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
}
else if(initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
}
else {
throw new IllegalArgumentException("Illegal Capacity: " +
initialCapacity);
}
}
复制代码
该构造函数可以传入一个 int 值,如果该值大于 0,则创建一个长度为该值的数组; 如果该值等于 0,则使用一个空数组;如果该值小于 0,则抛出IllegalArgumentException
异常。
ArrayList(Collection c)
- 使用
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("程序员小杰");
ArrayList<String> list = new ArrayList<>(arrayList);
复制代码
- 源码
public ArrayList(Collection <? extends E > c) {
elementData = c.toArray();
if((size = elementData.length) != 0) {
if(elementData.