ArrayList的实现原理就是大学数据结构书本中的动态数组原理,初始化一个Object数组,然后对Object数组进行插入,扩容,查找,删除等操作。所以可以看出java引用类型所占内存大小是一样的,Object数组类似于c语言中的void*指针数组,每个指针在64位机器上都占8字节, 在hotspot jvm中java引用类型也是占8字节。所以ArrayList无法存放基本类型,只能存放引用类型。以下分析ArrayList最基础,最常用的操作。
首先看ArrayList类关系图
Collection接口继承Iterable接口,所以所有实现了Collection接口的类都支持foreach遍历,List接口继承Collection接口,AbstractCollection接口实现了Collection接口,AbstractList继承AbstractCollection,提供了一些基础操作,如果我们自定义自己的List可以扩展AbstractList抽象类,ArrayList继承AbstractList,并且实现了List接口。这里再引出一个问题,为啥AbstractList实现了List接口,ArrayList是AbstractList的子类再实现一遍,也可以重写父类方法达到同样效果,我觉得是一种编码习惯,并且在对类进行反射操作时,用getInstance方法时子类如果不加implements 父类implements的接口,会获取不到接口。
/*
*ArrayList继承AbstractList类,并且实现了List接口
*/
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private static final long serialVersionUID = 8683452581122892189L;
//默认数组长度10
private static final int DEFAULT_CAPACITY = 10;
//初始化化一个空object数组,
private static final Object[] EMPTY_ELEMENTDATA = {};
//初始化一个空object数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//存元素的数组
transient Object[] elementData; // non-private to simplify nested class access
//数组大小
private int size;
//初始化数组大小的构造方法
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);
}
}
//无参构造方法,初始化一个空数组,不指定类型初始化时默认为OBJECT
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
//初始化一个存在的Collection,不指定类型时为? extends Object,
//指定类型后参数必须为E或者E的子类
public ArrayList(Collection<? extends E> c) {
//返回一个复制了c中的元素数组引用
//如果c的内部实现使用了Object数组,则返回Object[],否则返回对应数组
elementData = c.toArray();
if ((size = elementData.length) != 0) {
//如果不是object数组,则重新将elementData转换为Object[]数组
//如果不转换则会出现运行时报错,比如自定义一个类实现了Collection接口,类
//内部采用Integer[]数组存储元素,然后定义一个ArrayList<Number>对象,如果
//未转换,则这个对象存储Double数据时会抛出ArrayStoreException。
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
/**
* 确定数组容量,minCapacity表示所必须的最小容量
*/
private void ensureCapacityInternal(int minCapacity) {
//如果elementData是默认容量空数组,则选择默认容量和最小容量较大的一个
//做为最小容量
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++; //list修改次数+1
//如果数组长度小于所需的最小容量,则扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
//arraylist最大个数
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
//arraylist满之后,对Object数组扩容
private void grow(int minCapacity) {
// 原数组大小
int oldCapacity = elementData.length;
//新的大小为原来的3倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
//如果传进的参数大于扩容的参数,则按照传进的参数确定数组大小
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//如果扩容的参数大于数组最大容量
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
//获取一个新的扩容数组,并将原有元素复制到新数组
elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
/**
* 返回list大小,也就是Object数组大小
*/
public int size() {
return size;
}
/**
* 判断数组是否为空
*/
public boolean isEmpty() {
return size == 0;
}
/**
* 数组是否包含指定元素
*/
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
/**
* 返回元素所在数组的下标,从前往后搜索,如果找不到则返回-1
*/
public int indexOf(Object o) {
//如果是null元素则只返回第一个为null的下标
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else { //返回第一个为elementData[i]的下标
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
/**
* 返回元素所在数组的下标,从后往前搜索,如果找不到则返回-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;
}
/**
* 复制一个新的list
*/
public Object clone() {
try {
//返回一个新的引用,浅拷贝
ArrayList<?> v = (ArrayList<?>) 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(e);
}
}
/**
* 复制elementData数组,返回一个新的Object[]对象
*/
public Object[] toArray() {
return Arrays.copyOf(elementData, size);
}
/**
* 泛型方法,将elementData复制为T[]类型数组
*/
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
//如果a的长度小于elementData长度调用copyOf,新创建一个a类型的数组
if (a.length < size)
// Make a new array of a's runtime type, but my contents:
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
//如果小于等于则,直接复制到a数组
System.arraycopy(elementData, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
// 获取指定下标的元素
@SuppressWarnings("unchecked")
E elementData(int index) {
return (E) elementData[index];
}
/**
* 获取指定index的元素
*/
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
/**
* 设置指定index的元素
*/
public E set(int index, E element) {
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
/**
* 在list尾部添加元素
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
/**
* 移除指定位置的元素
*/
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;
}
/**
* 从前往后移除第一个和o相等的元素
*/
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
/*
* 移除 减少了边界检查
*/
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; //gc的时候会将elementData[i]指向的堆内存释放掉
}
/**
* 将集合对象c添加到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;
}
/**
* 数组边界检查
*/
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
/**
* 返回ListIterator迭代器,起始迭代位置是index
*/
public ListIterator<E> listIterator(int index) {
if (index < 0 || index > size)
throw new IndexOutOfBoundsException("Index: "+index);
return new ListItr(index);
}
/**
* 返回ListIterator迭代器,起始迭代位置是0
*/
public ListIterator<E> listIterator() {
return new ListItr(0);
}
/**
* 返回Iterator迭代器,起始位置是0
*/
public Iterator<E> iterator() {
return new Itr();
}
/**
* 私有内部类实现Iterator接口,使用Iterator遍历list,可以在遍历的过程中删除元素
*/
private class Itr implements Iterator<E> {
int cursor; // 数组当前游标
int lastRet = -1; // 初始化-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]; //
}
/**
* 移除最后一次遍历的位置的元素,如果连续调用remove则会出错,必须调用next()后才能调用remove
*/
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet; //游标等于移除的位置
lastRet = -1; //最后一次遍历的位置重置-1
expectedModCount = modCount; //给期望修改的次数重新赋值
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
/**
* ListIterator的实现类,主要实现了对list从后往前进行迭代,并且在迭代过程中
* 可以添加和修改元素
*/
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;
}
//返回从后往前将要遍历的元素下标
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 set(E e) {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.set(lastRet, e);
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
//在当前游标指定的位置添加元素
public void add(E e) {
checkForComodification();
try {
int i = cursor;
ArrayList.this.add(i, e);
cursor = i + 1; //添加完游标加一,从前往后遍历时刚添加的不会遍历到,从后往前会遍历到刚添加的
lastRet = -1; //重置lastRet
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
}