一、概述
ArrayList类提供了可调整大小的数组(动态数组),并实现了List接口。ArrayList类实现了所有可选的列表操作,并且允许所有元素,包括空值null。它提供了一些方法来操作内部用来存储列表的数组的大小。相较于LinkedList实现的常数因子较低。
二、功能
1、ArrayList 继承AbstractList,实现了List。它是一个数组队列,提供了相关的添加、删除、修改、遍历等功能。
2、提供了随机访问功能。
3、可以通过元素的序号快速获取元素对象。
4、支持序列化,能通过序列化去传输。
5、能被克隆。
三、特点
1、随机访问速度快,插入、删除、移动性能较差。
2、支持null元素。
3、有序。
4、元素可以重复。
5、线程不安全。
四、为什么说ArrayList是线程不安全的?
1、线程安全
线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。
2、线程不安全
线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据。
3、ArrayList是线程不安全的
private void ensureCapacityInternal(int minCapacity) {
if (elementData == EMPTY_ELEMENTDATA) { //若elementData=={},则取minCapacity为默认容量和参数minCapacity之间的最大值
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!! //确定ArrayList的容量大小
elementData[size++] = e; //添加e到ArrayList中,然后size自增 1
return true;
}
五、源码解析
ArrayList继承AbstractList,实现List、RandomAccess、Cloneable、java.io.Serializable接口。
AbstractList提供了List接口的默认实现。 List接口定义了列表必须实现的方法。RandomAccess是一个标记接口,接口内没有定义任何内容。实现Cloneable接口的类,可以调用Object.clone方法返回该对象的浅拷贝。通过实现 java.io.Serializable 接口以启用其序列化功能,序列化接口没有方法或字段,仅用于标识可序列化的语义。
//ArrayList<E>说明支持泛型
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 static final Object[] EMPTY_ELEMENTDATA = {}; //空数组
private transient Object[] elementData; //存储ArrayList内的元素;transient表示一个域不是该对象串行化的一部分,当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中
private int size; //ArrayList的大小(包含的元素数量)
ArrayList构造方法(initialCapacity初始化elementData数组的大小)
public ArrayList(int initialCapacity) { //initialCapacity为初始容量
super();
if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);//当初始容量非法时(小于0)抛出异常
this.elementData = new Object[initialCapacity];
}
ArrayList无参构造方法
public ArrayList() {
super();
this.elementData = EMPTY_ELEMENTDATA; //创建一个空的ArrayList,此时其数组缓冲区elementData={},默认elementData初始容量为10
}
ArrayList构造方法,将提供的集合转成数组返回给elementData
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray(); //返回包含c所有元素的数组
size = elementData.length; //将转换后的Object[]长度赋值给当前ArrayList的size
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class) //若c.toArray()返回的数组类型不是Object[],则利用 Arrays.copyOf()来构造一个大小为size的Object[]数组
elementData = Arrays.copyOf(elementData, size, Object[].class); //复制指定数组
}
将当前容量值设为当前实际元素大小
public void trimToSize() {
modCount++;
if (size < elementData.length) { //当实际大小<数组缓冲区大小
elementData = Arrays.copyOf(elementData, size); //调整数组缓冲区 elementData,变为实际存储大小
}
}
将集合的capacit增加minCapacity
public void ensureCapacity(int minCapacity) { //minCapacity为指定的最小容量
int minExpand = (elementData != EMPTY_ELEMENTDATA) //最小扩充容量,默认为10
// any size if real element table
? 0
// larger than default for empty table. It's already supposed to be
// at default size.
: DEFAULT_CAPACITY;
if (minCapacity > minExpand) { //若用户指定的最小容量>最小扩充容量,则以用户指定的为准,否则还是10
ensureExplicitCapacity(minCapacity);
}
}
明确 ArrarList 的容量
private void ensureCapacityInternal(int minCapacity) {
if (elementData == EMPTY_ELEMENTDATA) { //若elementData=={},则取minCapacity为默认容量和参数minCapacity之间的最大值
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
明确ArrayList的容量,用于内部优化,保证空间资源不被浪费
private void ensureExplicitCapacity(int minCapacity) {
modCount++; // 将"修改统计数"+1,该变量主要是用来实现fail-fast机制的
// overflow-conscious code
if (minCapacity - elementData.length > 0) //确保指定的最小容量>数组缓冲区当前的长度,防止溢出代码
grow(minCapacity);
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; //数组缓冲区最大存储容量
获取该 list 所实际存储的元素个数
public int size() {
return size;
}
判断list是否为空
public boolean isEmpty() {
return size == 0;
}
判断该 ArrayList是否包含Object类型对象
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
顺序查找,返回元素的最低索引值
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++) //顺序查找数组缓冲区
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
反向查找,返回元素的最高索引值
public int lastIndexOf(Object o) {
if (o == null) {
for (int i = size-1; i >= 0; i--) //逆序查找
if (elementData[i]==null)
return i;
} else {
for (int i = size-1; i >= 0; i--)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
深度复制:对拷贝出来的ArrayList对象的操作,不会影响原来的ArrayList
Object 的clone()方法会复制本对象及其内所有基本类型成员和 String 类型成员,但不会复制对象成员、引用对象
public Object clone() {
try {
@SuppressWarnings("unchecked")
ArrayList<E> v = (ArrayList<E>) super.clone();
v.elementData = Arrays.copyOf(elementData, size); //对需要进行复制的引用变量,进行独立的拷贝
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
}
返回ArrayList的Object数组
对返回的该数组进行操作,不会影响该 ArrayList
public Object[] toArray() {
return Arrays.copyOf(elementData, size);
}
返回 ArrayList 元素组成的数组
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) { //a为需要存储 list 中元素的数组
if (a.length < size) //若数组a的大小<ArrayList的长度,则将ArrayList全部拷贝到T[]中
// Make a new array of a's runtime type, but my contents:
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
System.arraycopy(elementData, 0, a, 0, size);
if (a.length > size) //若数组a的大小>ArrayList的长度,则将ArrayList的全部元素拷贝到数组a中
a[size] = null;
return a;
}
返回在索引为 index 的元素
@SuppressWarnings("unchecked")
E elementData(int index) {
return (E) elementData[index];
}
获取指定位置的元素:从0开始计数
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
设置index位置元素的值
public E set(int index, E element) {
rangeCheck(index); //设置 index 位置元素的值
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
向elementData中添加元素
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!! //确定ArrayList的容量大小
elementData[size++] = e; //添加e到ArrayList中,然后size自增 1
return true;
}
在指定位置插入新元素,原先在index位置的值往后移动一位
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
移除指定索引位置的元素:index之后的所有元素依次左移一位
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1; //需要左移的元素个数
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,numMoved);
elementData[--size] = null; // clear to let GC do its work //将最后一个元素置空
return oldValue;
}
删除ArrayList中的指定元素,只会删除一个
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) { //判断是否存储了null
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++) //遍历ArrayList找到“元素o”,则删除,并返回true
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
快速删除第index个元素
private void fastRemove(int index) {
modCount++;
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,numMoved);
elementData[--size] = null; // clear to let GC do its work
}
清空所有存储元素,它会将数组缓冲区所以元素置为null
public void clear() {
modCount++;
// clear to let GC do its work
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
将一个集合的所有元素顺序添加到list末尾
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length; //要添加的元素个数
ensureCapacityInternal(size + numNew); // Increments modCount //扩容
System.arraycopy(a, 0, elementData, size, numNew); //添加
size += numNew;
return numNew != 0;
}
从 index 位置开始,将集合 c 中的元素添加到ArrayList,并不会覆盖掉在index位置原有的值
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
int numMoved = size - index; //要移动的元素个数
if (numMoved > 0)
System.arraycopy(elementData, index, elementData, index + numNew,numMoved);
System.arraycopy(a, 0, elementData, index, numNew);
size += numNew;
return numNew != 0;
}
删除fromIndex到toIndex之间的全部元素
protected void removeRange(int fromIndex, int toIndex) {
modCount++;
int numMoved = size - toIndex;
System.arraycopy(elementData, toIndex, elementData, fromIndex,numMoved);
// clear to let GC do its work
int newSize = size - (toIndex-fromIndex);
for (int i = newSize; i < size; i++) {
elementData[i] = null;
}
size = newSize;
}
提供给get()、remove()等方法检查给出的索引值 index 是否越界
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
提供给add()和add()进行数组越界检查的方法
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
返回异常消息,用于传给IndexOutOfBoundsException
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+size;
}
移除list中和c中共有的元素
public boolean removeAll(Collection<?> c) {
return batchRemove(c, false);
}
只保留list和集合c中公有的元素
public boolean retainAll(Collection<?> c) {
return batchRemove(c, true);
}
批量删除
private boolean batchRemove(Collection<?> c, boolean complement) {
final Object[] elementData = this.elementData;
int r = 0, w = 0;
boolean modified = false;
try {
for (; r < size; r++)
if (c.contains(elementData[r]) == complement)
elementData[w++] = elementData[r];
} finally {
// Preserve behavioral compatibility with AbstractCollection,
// even if c.contains() throws.
if (r != size) {
System.arraycopy(elementData, r,
elementData, w,
size - r);
w += size - r;
}
if (w != size) {
// clear to let GC do its work
for (int i = w; i < size; i++)
elementData[i] = null;
modCount += size - w;
size = w;
modified = true;
}
}
return modified;
}
序列化函数
private void writeObject(java.io.ObjectOutputStream s)throws java.io.IOException{
// Write out element count, and any hidden stuff
int expectedModCount = modCount;
s.defaultWriteObject();
// Write out size as capacity for behavioural compatibility with clone()
s.writeInt(size); //写入ArrayList大小
// Write out all elements in the proper order.
for (int i=0; i<size; i++) { //写入存储的元素
s.writeObject(elementData[i]);
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
private void readObject(java.io.ObjectInputStream s)throws java.io.IOException, ClassNotFoundException { //先将ArrayList的容量读出,然后将所有的元素值读出
elementData = EMPTY_ELEMENTDATA;
// Read in size, and any hidden stuff
s.defaultReadObject();
// Read in capacity
s.readInt(); // ignored //从输入流中读取ArrayList的size
if (size > 0) {
// be like clone(), allocate array based upon size not capacity
ensureCapacityInternal(size);
Object[] a = elementData;
// Read in all elements in the proper order.
for (int i=0; i<size; i++) { //从输入流中将所有的元素值读出
a[i] = s.readObject();
}
}
}
返回一个ListIterator
public ListIterator<E> listIterator(int index) {
if (index < 0 || index > size)throw new IndexOutOfBoundsException("Index: "+index);
return new ListItr(index);
}
返回一个Iterator迭代器,该迭代器是fail-fast机制的
public Iterator<E> iterator() {
return new Itr();
}
private class Itr implements Iterator<E> {
int cursor; // index of next element to return //下一个返回元素的索引,默认值为0
int lastRet = -1; // index of last element returned; -1 if no such //上一个返回元素的索引,若没有上一个元素,则为-1
int expectedModCount = modCount;
public boolean hasNext() { //是否有下一元素的判断
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor; //指向游标当前位置
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
ListItr继承Itr,实现ListIterator接口,可以进行双向移动,可以添加元素(有add()方法)
private class ListItr extends Itr implements ListIterator<E> {
ListItr(int index) { //指向下一个返回元素的索引位置
super();
cursor = index;
}
是否有上一个元素
public boolean hasPrevious() {
return cursor != 0;
}
获取下一个元素的索引
public int nextIndex() {
return cursor;
}
获取 cursor 前一个元素的索引
public int previousIndex() {
return cursor - 1;
}
返回 cursor 前一元素
@SuppressWarnings("unchecked")
public E previous() {
checkForComodification();
int i = cursor - 1;
if (i < 0)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i;
return (E) elementData[lastRet = i];
}
添加元素:在游标当前指向的索引位置插入一个元素
public void add(E e) {
checkForComodification();
try {
int i = cursor;
ArrayList.this.add(i, e);
cursor = i + 1;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
}
获取从fromIndex到toIndex之间的子集合
public List<E> subList(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size); //合法性检查
return new SubList(this, 0, fromIndex, toIndex);
}
static void subListRangeCheck(int fromIndex, int toIndex, int size) {
if (fromIndex < 0) //越界检查
throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
if (toIndex > size)
throw new IndexOutOfBoundsException("toIndex = " + toIndex);
if (fromIndex > toIndex) //非法参数检查
throw new IllegalArgumentException("fromIndex(" + fromIndex +
") > toIndex(" + toIndex + ")");
}
嵌套内部类,继承AbstractList,实现RandomAccess接口
private class SubList extends AbstractList<E> implements RandomAccess {
private final AbstractList<E> parent;
private final int parentOffset;
private final int offset;
int size;
SubList(AbstractList<E> parent,
int offset, int fromIndex, int toIndex) {
this.parent = parent;
this.parentOffset = fromIndex;
this.offset = offset + fromIndex;
this.size = toIndex - fromIndex;
this.modCount = ArrayList.this.modCount;
}
设置新值,返回旧值
public E set(int index, E e) {
rangeCheck(index);
checkForComodification();
E oldValue = ArrayList.this.elementData(offset + index);
ArrayList.this.elementData[offset + index] = e;
return oldValue;
}
取值
public E get(int index) {
rangeCheck(index);
checkForComodification();
return ArrayList.this.elementData(offset + index);
}
添加元素
public void add(int index, E e) {
rangeCheckForAdd(index);
checkForComodification();
parent.add(parentOffset + index, e); //对子类添加元素,是直接操作父类添加的
this.modCount = parent.modCount;
this.size++;
}
删除元素
public E remove(int index) {
rangeCheck(index);
checkForComodification();
E result = parent.remove(parentOffset + index); //对子类删除元素,是直接操作父类删除的
this.modCount = parent.modCount;
this.size--;
return result;
}
范围删除
protected void removeRange(int fromIndex, int toIndex) {
checkForComodification();
parent.removeRange(parentOffset + fromIndex,
parentOffset + toIndex);
this.modCount = parent.modCount;
this.size -= toIndex - fromIndex;
}
返回一个迭代器
public Iterator<E> iterator() {
return listIterator();
}