JDK1.8源码解析之 ArrayList

194 阅读6分钟

概述

概念

List接口可调整大小的数组实现。实现所有可选的List操作,并允许所有元素,包括null,元素可重复。 除了列表接口外,该类提供了一种方法来操作该数组的大小来存储该列表中的数组的大小。

时间复杂度

方法size、isEmpty、get、set、iterator和listIterator的调用是常数时间的。 添加删除的时间复杂度为O(N)。其他所有操作也都是线性时间复杂度。

容量

每个ArrayList都有容量,容量大小至少为List元素的长度,默认初始化为10。容量可以自动增长。如果提前知道数组元素较多,可以在添加元素前通过调用ensureCapacity()方法提前增加容量以减小后期容量自动增长的开销。也可以通过带初始容量的构造器初始化这个容量。

线程不安全

ArrayList不是线程安全的。如果需要应用到多线程中,需要在外部做同步

modCount

定义在AbstractList中:protected transient int modCount = 0; 已从结构上修改此列表的次数。从结构上修改是指更改列表的大小,或者打乱列表,从而使正在进行的迭代产生错误的结果。 此字段由iterator和listiterator方法返回的迭代器和列表迭代器实现使用。 如果意外更改了此字段中的值,则迭代器(或列表迭代器)将抛出concurrentmodificationexception来响应next、remove、previous、set或add操作。 在迭代期间面临并发修改时,它提供了快速失败 行为,而不是非确定性行为。 子类是否使用此字段是可选的。 如果子类希望提供快速失败迭代器(和列表迭代器),则它只需在其 add(int,e)和remove(int)方法(以及它所重写的、导致列表结构上修改的任何其他方法)中增加此字段。 对add(int, e)或remove(int)的单个调用向此字段添加的数量不得超过 1,否则迭代器(和列表迭代器)将抛出虚假的 concurrentmodificationexceptions。 如果某个实现不希望提供快速失败迭代器,则可以忽略此字段。

transient

默认情况下,对象的所有成员变量都将被持久化.在某些情况下,如果你想避免持久化对象的一些成员变量,你可以使用transient关键字来标记他们,transient也是java中的保留字(JDK 1.8)

继承关系

public class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable 继承了 AbstractList 类 实现了 List, RandomAccess, Cloneable, java.io.Serializable接口

成员属性

  • private static final int DEFAULT_CAPACITY = 10; 默认容量

  • private static final Object[] EMPTY_ELEMENTDATA = {}; 空的对象数组

  • private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; 默认的空数组 无参构造函数创建的数组

  • transient Object[] elementData; 存放数据的数组的缓存变量,不可序列化

  • private int size; private int size;

构造器

带有容量initialCapacity的构造方法

public ArrayList(int initialCapacity)

不带参数的构造方法

public ArrayList()

带参数Collection的构造方法,将指定的Collection中的元素放入当前对象。

public ArrayList(Collection<? extends E> c)

关键方法

因为容量常常会大于实际元素的数量。内存紧张时,可以调用该方法删除预留的位置,调整容量为元素实际数量。如果确定不会再有元素添加进来时也可以调用该方法来节约空间

public void trimToSize()
ensureCapacity()

使用指定参数设置数组容量

public void ensureCapacity(int minCapacity)
size()

返回ArrayList的大小

public int size() {
    return size;
}
isEmpty()

判断是否为空

public boolean isEmpty() {
    return size == 0;
}
contains()

是否包含一个数 返回bool

public boolean contains(Object o)
indexOf()

返回一个值在数组首次出现的位置,会根据是否为null使用不同方式判断。不存在就返回-1。时间复杂度为O(N)

public int indexOf(Object o)
lastIndexOf()

返回一个值在数组最后一次出现的位置,会根据是否为null使用不同方式判断。不存在就返回-1。时间复杂度为O(N)

public int lastIndexOf(Object o)
clone()

返回副本,元素本身没有被复制,复制过程数组发生改变会抛出异常

public Object clone()
toArray()

转换为Object数组,使用Arrays.copyOf()方法

public Object[] toArray()

如果a的长度比ArrayList的长度大,那么就调用System.arraycopy,将ArrayList的elementData数组赋值到a数组,然后把a数组的size位置赋值为空。

@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a)
get()

返回指定位置的值,但是会先检查这个位置数否超出数组长度

public E get(int index)
set()

设置指定位置为一个新值,并返回之前的值,会检查这个位置是否超出数组长度

public E set(int index, E element)
add()

添加一个值,首先会确保容量

public boolean add(E e) 

在ArrayList的index位置,添加元素element,会检查添加的位置和容量

public void add(int index, E element)
remove()

在ArrayList的移除index位置的元素,会检查添加的位置,返回之前的值

public E remove(int index)

在ArrayList的移除对象为O的元素,跟indexOf方法思想基本一致

public boolean remove(Object o)
clear()

清空数组,把每一个值设为null,方便垃圾回收(不同于reset,数组默认大小有改变的话不会重置)

public void clear()
addAll()

添加一个集合的元素到末端,若要添加的集合为空返回false

public boolean addAll(Collection<? extends E> c)

从第index位开始,将c全部拷贝到ArrayList,若要添加的集合为空返回false

 public boolean addAll(int index, Collection<? extends E> c)
removeAll()

移除该对象中,所有包含在c中的元素

public boolean removeAll(Collection<?> c)
retainAll()

仅保留指定集合c中的元素

public boolean retainAll(Collection<?> c)
listIterator()

返回一个从index开始的ListIterator对象

public ListIterator<E> listIterator(int index)

返回一个ListIterator对象,ListItr为ArrayList的一个内部类,其实现了ListIterator 接口

public ListIterator<E> listIterator()

返回一个Iterator对象,Itr为ArrayList的一个内部类,其实现了Iterator接口

public Iterator<E> iterator()
subList()

根据序号返回指定范围内的元素组成的List

public List<E> subList(int fromIndex, int toIndex)
forEach()

遍历

@Override
public void forEach(Consumer<? super E> action)
spliterator()

在此列表中的元素上创建一个后期绑定和快速失败的Spliterator

@Override
public Spliterator<E> spliterator()
removeIf()

作用是按照一定规则过滤集合中的元素。

@Override
public boolean removeIf(Predicate<? super E> filter)
replaceAll()
@Override
@SuppressWarnings("unchecked")
public void replaceAll(UnaryOperator<E> operator)
sort()

根据指定的 Comparator 排序

@Override
@SuppressWarnings("unchecked")
public void sort(Comparator<? super E> c)

希望和大家多多交流


我16年毕业以后,做的是前端,目前打算深入学习java开发。内容有任何问题,欢迎各位小伙伴们指正,也希望小伙伴们给我点赞和关注,给我留言,一起交流讨论,共同进步。