ArrayList是继承AbstractList,并实现了Cloneable,Serializable,RandomAccess接口。
不明白AbstractList,和Cloneable,Serializable,RandomAccess接口的请查看以下博客内容。
关于Cloneable ,Serializable接口请参看
http://kentkwan.iteye.com/blog/739514
关于请参看我的另一张博客:
http://blog.csdn.net/bibi_love2008/article/details/52669646
RandomAccess接口:
https://my.oschina.net/u/1466553/blog/496024。
准备工作做好之后,我们先上源码,在源码中我以注释的方式,来表达我的理解。
public class ArrayList<E> extends AbstractList<E> implements Cloneable, Serializable, RandomAccess {
/**
* The minimum amount by which the capacity of an ArrayList will increase.
* This tuning parameter controls a time-space tradeoff. This value (12)
* gives empirically good results and is arguably consistent with the
* RI's specified default initial capacity of 10: instead of 10, we start
* with 0 (sans allocation) and jump to 12.
*/
private static final int MIN_CAPACITY_INCREMENT = 12;//当空间不够时,默认最小增长12个数组
/**
* The number of elements in this list.
*/
int size;//集合中元素的个数
/**
* The elements in this list, followed by nulls.
*/
transient Object[] array;//Arraylist底层是由数组形式实现的
/**
* Constructs a new instance of {@code ArrayList} with the specified
* initial capacity.
*
* @param capacity
* the initial capacity of this {@code ArrayList}.
*/
public ArrayList(int capacity) {
//构造方法,capacity代表初始化数组的大小
if (capacity < 0) {//当capacity <0时,则抛出IllegalArgumentException
throw new IllegalArgumentException("capacity < 0: " + capacity);
}
//三元运算符,当capacity =0时,EmptyArray.OBJECT,当capacity>0,时则new Object数组,数组大小是 capacity
}
/**
* Constructs a new {@code ArrayList} instance with zero initial capacity.
*/
public ArrayList() {
//无参构造方法。将EmptyArray.OBJECT赋值给array ,EmptyArray.OBJECT 是Object []obj=new Object[0];
array = EmptyArray.OBJECT;
}
/**
* Constructs a new instance of {@code ArrayList} containing the elements of
* the specified collection.
*
* @param collection
* the collection of elements to add.
*/
public ArrayList(Collection extends E> collection) {//构造函数,参数为Collection集合
if (collection == null) {//当collection =null时,会抛出NullPointerException异常。
throw new NullPointerException("collection == null");
}
Object[] a = collection.toArray();//将collection集合转换成Object数组
//判断一下数据类型是不是Object[]类型,(说明一下: Object[] a = //new Object[3];和Integer[] b = new Integer[3];他们两个的类型是不相等的),
//如果不是Object[]类型,则新创建一个长度为a.length的Object数组,//并把数组拷贝到新的Object数组,把新的数组赋值给a
Object[] newArray = new Object[a.length];
System.arraycopy(a, 0, newArray, 0, a.length);
a = newArray;
}
array = a;//将a数组赋值给array
size = a.length;//元素个数为a.length
}
/**
* Adds the specified object at the end of this {@code ArrayList}.
*
* @param object
* the object to add.
* @return always true
*/
@Override public boolean add(E object) {//向arrayList中添加元素,
Object[] a = array;//先将array赋值给一个临时的环境变量a
int s = size;//计入当前添加ArrayList中的元素的个数
if (s == a.length) {
//判断当前容器是否已经满了,如果满了,就需要扩容。扩容规则:当前容器小于MIN_CAPACITY_INCREMENT / 2时,则增加个MIN_CAPACITY_INCREMENT个,否则增加s/2个空间。,(说明:左移运算符,num << 1,相当于num乘以2,右移运算符,num >> 1,相当于num除以2),并将旧的数据拷贝到新的数组。并赋值给array.
Object[] newArray = new Object[s +
(s < (MIN_CAPACITY_INCREMENT / 2) ?
MIN_CAPACITY_INCREMENT : s >> 1)];
System.arraycopy(a, 0, newArray, 0, s);
array = a = newArray;
}
a[s] = object;
size = s + 1;
modCount++;
return true;
}
/**
* Inserts the specified object into this {@code ArrayList} at the specified
* location. The object is inserted before any previous element at the
* specified location. If the location is equal to the size of this
* {@code ArrayList}, the object is added at the end.
*
* @param index
* the index at which to insert the object.
* @param object
* the object to add.
* @throws IndexOutOfBoundsException
* when {@code location < 0 || location > size()}
*/
@Override public void add(int index, E object) {//添加元素到指定位置
Object[] a = array;
int s = size;
if (index > s || index < 0) {//当index大于容器大小时,或index<0时则抛出IndexOutOfBoundException
throwIndexOutOfBoundsException(index, s);
}
if (s < a.length) {//当容器空间够用时,通过数组coppy方式移动数组
System.arraycopy(a, index, a, index + 1, s - index);
} else {//当容器空间不够用时,创建新的数组,并将数据拷贝到新的数组中。并在新的数组中移动位置
// assert s == a.length;
Object[] newArray = new Object[newCapacity(s)];
System.arraycopy(a, 0, newArray, 0, index);
System.arraycopy(a, index, newArray, index + 1, s - index);
array = a = newArray;
}
a[index] = object;
size = s + 1;
modCount++;
}
/**
* This method controls the growth of ArrayList capacities. It represents
* a time-space tradeoff: we don't want to grow lists too frequently
* (which wastes time and fragments storage), but we don't want to waste
* too much space in unused excess capacity.
*
* NOTE: This method is inlined into {@link #add(Object)} for performance.
* If you change the method, change it there too!
*/
private static int newCapacity(int currentCapacity) {//扩容规则:当前容器小于MIN_CAPACITY_INCREMENT / 2时,则增加个MIN_CAPACITY_INCREMENT个,否则增加s/2个空间。,
//(说明:左移运算符,num << 1,相当于num乘以2,右移运算符,num >> 1,相当于num除以2)
int increment = (currentCapacity < (MIN_CAPACITY_INCREMENT / 2) ?
MIN_CAPACITY_INCREMENT : currentCapacity >> 1);
return currentCapacity + increment;
}
/**
* Adds the objects in the specified collection to this {@code ArrayList}.
*
* @param collection
* the collection of objects.
* @return {@code true} if this {@code ArrayList} is modified, {@code false}
* otherwise.
*/
@Override public boolean addAll(Collection extends E> collection) {//添加一个集合到容器中,返回值为boolean类型,添加成功为true,失败为false
Object[] newPart = collection.toArray();//先将collection转化为数组
int newPartSize = newPart.length;//获取数组长度
if (newPartSize == 0) {//如果collection集合为空则添加失败。
return false;
}
Object[] a = array;//创建一个局部变量,将当前容器中的array赋值给a。
int s = size;//获取当前容器中的大小
int newSize = s + newPartSize; //计算出添加之后所需要的容器大小
if (newSize > a.length) {//当新增加之后的容器大小,大于原有容的大小时则进行扩容。扩容规则请看newCapacity注释
int newCapacity = newCapacity(newSize - 1); // ~33% growth room
Object[] newArray = new Object[newCapacity];
System.arraycopy(a, 0, newArray, 0, s);
array = a = newArray;
}
System.arraycopy(newPart, 0, a, s, newPartSize);
size = newSize;
modCount++;
return true;
}
/**
* Inserts the objects in the specified collection at the specified location
* in this List. The objects are added in the order they are returned from
* the collection's iterator.
*
* @param index
* the index at which to insert.
* @param collection
* the collection of objects.
* @return {@code true} if this {@code ArrayList} is modified, {@code false}
* otherwise.
* @throws IndexOutOfBoundsException
* when {@code location < 0 || location > size()}
*/
@Override
public boolean addAll(int index, Collection extends E> collection) {//将集合插入到容器中指定的位置。返回类型boolean值,true为添加成功,false为添加失败。
int s = size;
if (index > s || index < 0) {//当index<0或者index大约当前容器长度则抛出IndexOutOfBoundsException异常
throwIndexOutOfBoundsException(index, s);
}
Object[] newPart = collection.toArray();//将传入的collection参数转换成Object数组。
int newPartSize = newPart.length;获取传入集合的长度
if (newPartSize == 0) {//当传入集合为空时,则返回false
return false;
}
Object[] a = array;//原理与addAll方式一样,不在这里过多注释
int newSize = s + newPartSize; // If add overflows, arraycopy will fail
if (newSize <= a.length) {
System.arraycopy(a, index, a, index + newPartSize, s - index);
} else {
int newCapacity = newCapacity(newSize - 1); // ~33% growth room
Object[] newArray = new Object[newCapacity];
System.arraycopy(a, 0, newArray, 0, index);
System.arraycopy(a, index, newArray, index + newPartSize, s-index);
array = a = newArray;
}
System.arraycopy(newPart, 0, a, index, newPartSize);
size = newSize;
modCount++;
return true;
}
/**
* This method was extracted to encourage VM to inline callers.
* TODO: when we have a VM that can actually inline, move the test in here too!
*/
static IndexOutOfBoundsException throwIndexOutOfBoundsException(int index, int size) {
throw new IndexOutOfBoundsException("Invalid index " + index + ", size is " + size);
}
/**
清空容器,将容器中数组中的对象都设置为null.
具有以下功能:
1、 给数组赋值:通过fill方法。
2、对数组排序:通过sort方法,按升序。
3、比较数组:通过equals方法比较数组中元素值是否相等。
4、查找数组元素:通过binarySearch方法能对排序好的数组进行二分查找法操作。)
*/
@Override public void clear() {
if (size != 0) {
Arrays.fill(array, 0, size, null);
size = 0;
modCount++;
}
}
/**
复制,ArrayList实现了Cloneable接口,clone方法的作用。
这个复制函数返回的是一个新对象而不是一个引用。使用clone方法需要实现clone的类继承Cloneable接口。(Cloneable接口是一个标识接口。),
在类中重写clone方法,在clone方法中调用super.clone(),
无论clone类的继承结构是什么,
super.clone()都会直接的或者间接的调用java.lang.Object类中的clone()方法。
把浅复制的引用指向原型中的克隆体。
(浅复制:被复制的对象的所有变量都含有与原来对象相同的值,
而所有对其它对象的引用仍然指向原来的对象。换言之,浅复制对象仅仅复制的考虑的对象,而不复制它所引用的对象。
深复制:被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其它对象的变量。那些引用其它对象的变量将指向被复制的新对象,而不再是原有的那些被引用的对象)
*/
@Override public Object clone() {//
try {
ArrayList> result = (ArrayList>) super.clone();
result.array = array.clone();
return result;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
/**
* Ensures that after this operation the {@code ArrayList} can hold the
* specified number of elements without further growing.
*
* @param minimumCapacity
* the minimum capacity asked for.
*/
public void ensureCapacity(int minimumCapacity) {
Object[] a = array;
if (a.length < minimumCapacity) {
Object[] newArray = new Object[minimumCapacity];
System.arraycopy(a, 0, newArray, 0, size);
array = newArray;
modCount++;
}
}
@SuppressWarnings("unchecked") @Override public E get(int index) {
if (index >= size) {
throwIndexOutOfBoundsException(index, size);
}
return (E) array[index];
}
/**
* Returns the number of elements in this {@code ArrayList}.
*
* @return the number of elements in this {@code ArrayList}.
*/
@Override public int size() {
return size;
}
@Override public boolean isEmpty() {
return size == 0;
}
/**
* Searches this {@code ArrayList} for the specified object.
*
* @param object
* the object to search for.
* @return {@code true} if {@code object} is an element of this
* {@code ArrayList}, {@code false} otherwise
*/
@Override public boolean contains(Object object) {
Object[] a = array;
int s = size;
if (object != null) {
for (int i = 0; i < s; i++) {
if (object.equals(a[i])) {
return true;
}
}
} else {
for (int i = 0; i < s; i++) {
if (a[i] == null) {
return true;
}
}
}
return false;
}
@Override public int indexOf(Object object) {
Object[] a = array;
int s = size;
if (object != null) {
for (int i = 0; i < s; i++) {
if (object.equals(a[i])) {
return i;
}
}
} else {
for (int i = 0; i < s; i++) {
if (a[i] == null) {
return i;
}
}
}
return -1;
}
/***
重写了AbstractList中的lastIndexOf方法,在AbstractList中lastIndex方法利用了迭代器FullListIterator实现了这个方法。
而在ArrayList中却直接遍历数组,没有沿用父类的方法。
体现了java中的多态
*/
@Override public int lastIndexOf(Object object) {//
Object[] a = array;
if (object != null) {
for (int i = size - 1; i >= 0; i--) {
if (object.equals(a[i])) {
return i;
}
}
} else {
for (int i = size - 1; i >= 0; i--) {
if (a[i] == null) {
return i;
}
}
}
return -1;
}
/**
* Removes the object at the specified location from this list.
*
* @param index
* the index of the object to remove.
* @return the removed object.
* @throws IndexOutOfBoundsException
* when {@code location < 0 || location >= size()}
*/
@Override public E remove(int index) {
Object[] a = array;
int s = size;
if (index >= s) {
throwIndexOutOfBoundsException(index, s);
}
@SuppressWarnings("unchecked") E result = (E) a[index];
System.arraycopy(a, index + 1, a, index, --s - index);
a[s] = null; // Prevent memory leak
size = s;
modCount++;
return result;
}
@Override public boolean remove(Object object) {
Object[] a = array;
int s = size;
if (object != null) {
for (int i = 0; i < s; i++) {
if (object.equals(a[i])) {
System.arraycopy(a, i + 1, a, i, --s - i);
a[s] = null; // Prevent memory leak
size = s;
modCount++;
return true;
}
}
} else {
for (int i = 0; i < s; i++) {
if (a[i] == null) {
System.arraycopy(a, i + 1, a, i, --s - i);
a[s] = null; // Prevent memory leak
size = s;
modCount++;
return true;
}
}
}
return false;
}
@Override protected void removeRange(int fromIndex, int toIndex) {
if (fromIndex == toIndex) {
return;
}
Object[] a = array;
int s = size;
if (fromIndex >= s) {
throw new IndexOutOfBoundsException("fromIndex " + fromIndex
+ " >= size " + size);
}
if (toIndex > s) {
throw new IndexOutOfBoundsException("toIndex " + toIndex
+ " > size " + size);
}
if (fromIndex > toIndex) {
throw new IndexOutOfBoundsException("fromIndex " + fromIndex
+ " > toIndex " + toIndex);
}
System.arraycopy(a, toIndex, a, fromIndex, s - toIndex);
int rangeSize = toIndex - fromIndex;
Arrays.fill(a, s - rangeSize, s, null);
size = s - rangeSize;
modCount++;
}
/**
* Replaces the element at the specified location in this {@code ArrayList}
* with the specified object.
*
* @param index
* the index at which to put the specified object.
* @param object
* the object to add.
* @return the previous element at the index.
* @throws IndexOutOfBoundsException
* when {@code location < 0 || location >= size()}
*/
@Override public E set(int index, E object) {//更新坐标为index的元素内容为object
Object[] a = array;
if (index >= size) {
throwIndexOutOfBoundsException(index, size);
}
@SuppressWarnings("unchecked") E result = (E) a[index];
a[index] = object;
return result;
}
/**
* Returns a new array containing all elements contained in this
* {@code ArrayList}.
*
* @return an array of the elements from this {@code ArrayList}
*/
@Override public Object[] toArray() {
int s = size;
Object[] result = new Object[s];
System.arraycopy(array, 0, result, 0, s);
return result;
}
/**
T是代表任意一种类型,这是泛型里的问题,是一种形式,表示你用的是泛型编程,不受类型的约束
*/
@Override public T[] toArray(T[] contents) {
int s = size;
if (contents.length < s) {
@SuppressWarnings("unchecked") T[] newArray
= (T[]) Array.newInstance(contents.getClass().getComponentType(), s);
contents = newArray;
}
System.arraycopy(this.array, 0, contents, 0, s);
if (contents.length > s) {
contents[s] = null;
}
return contents;
}
/**
* Sets the capacity of this {@code ArrayList} to be the same as the current
* size.
*
* @see #size
*/
public void trimToSize() {//整理容器空间,我们从clear方法中看到我们只是将数组中的元素设置为null,但是数组占用的空间并没有进行设置。我理解为ArrayList为了复用ArrayList,避免过多的创建内存空间,所以在clear的时候,并没有更改底层array的大小。于是提供了trimToSize.
int s = size;
if (s == array.length) {//当前元素个数等于容器大小,则什么也不做。直接return
return;
}
if (s == 0) {//当size=0时。将容器设置为长度为0的属猪
array = EmptyArray.OBJECT;
} else {//否则创建一个新的大小为当前size的数组。
Object[] newArray = new Object[s];
System.arraycopy(array, 0, newArray, 0, s);
array = newArray;
}
modCount++;
}
@Override public Iterator iterator() {//迭代遍历器
return new ArrayListIterator();
}
private class ArrayListIterator implements Iterator<E> {
/** Number of elements remaining in this iteration */
private int remaining = size;//当前容器中的大小
/** Index of element that remove() would remove, or -1 if no such elt */
private int removalIndex = -1;//删除的坐标
/** The expected modCount value */
private int expectedModCount = modCount;
public boolean hasNext() {
return remaining != 0;
}
@SuppressWarnings("unchecked") public E next() {
ArrayList ourList = ArrayList.this;
int rem = remaining;
if (ourList.modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
if (rem == 0) {
throw new NoSuchElementException();
}
remaining = rem - 1;
return (E) ourList.array[removalIndex = ourList.size - rem];
}
public void remove() {
Object[] a = array;
int removalIdx = removalIndex;
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
if (removalIdx < 0) {
throw new IllegalStateException();
}
System.arraycopy(a, removalIdx + 1, a, removalIdx, remaining);
a[--size] = null; // Prevent memory leak
removalIndex = -1;
expectedModCount = ++modCount;
}
}
@Override public int hashCode() {
Object[] a = array;
int hashCode = 1;
for (int i = 0, s = size; i < s; i++) {
Object e = a[i];
hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode());
}
return hashCode;
}
@Override public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof List)) {
return false;
}
List> that = (List>) o;
int s = size;
if (that.size() != s) {
return false;
}
Object[] a = array;
if (that instanceof RandomAccess) {
for (int i = 0; i < s; i++) {
Object eThis = a[i];
Object ethat = that.get(i);
if (eThis == null ? ethat != null : !eThis.equals(ethat)) {
return false;
}
}
} else { // Argument list is not random access; use its iterator
Iterator> it = that.iterator();
for (int i = 0; i < s; i++) {
Object eThis = a[i];
Object eThat = it.next();
if (eThis == null ? eThat != null : !eThis.equals(eThat)) {
return false;
}
}
}
return true;
}
private static final long serialVersionUID = 8683452581122892189L;
private void writeObject(ObjectOutputStream stream) throws IOException {//序列化
stream.defaultWriteObject();
stream.writeInt(array.length);
for (int i = 0; i < size; i++) {
stream.writeObject(array[i]);
}
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {//反序列化
stream.defaultReadObject();
int cap = stream.readInt();
if (cap < size) {
throw new InvalidObjectException(
"Capacity: " + cap + " < size: " + size);
}
array = (cap == 0 ? EmptyArray.OBJECT : new Object[cap]);
for (int i = 0; i < size; i++) {
array[i] = stream.readObject();
}
}
}
在我的android 环境中找不到这个EmptyArray 源码,现在从网络上找到源码,源码如下:
package libcore.util;
public final class EmptyArray {
private EmptyArray() {}
public static final boolean[] BOOLEAN = new boolean[0];
public static final byte[] BYTE = new byte[0];
public static final char[] CHAR = new char[0];
public static final double[] DOUBLE = new double[0];
public static final int[] INT = new int[0];
public static final Class>[] CLASS = new Class[0];
public static final Object[] OBJECT = new Object[0];
public static final String[] STRING = new String[0];
public static final Throwable[] THROWABLE = new Throwable[0];
public static final StackTraceElement[] STACK_TRACE_ELEMENT = new StackTraceElement[0];
}
总结:线性表的顺序存储结构,也称为顺序表,指用一段连续的存储单元依次存储线性表中的数据元素。
根据顺序表的特性,我们用数组来实现顺序表,ArrayList实现了线性表中的顺序表。