ArrayList是java中最常使用的动态数组,其具体使用方式就再也不介绍,本文只是从源码角度介绍它内部的序列化和扩容机制。ArrayList做为集合框架中的一员,它的继承关系以下所示:java
public class ArrayList<E> extends AbstractList<E> implements Cloneable, Serializable, RandomAccess
从它实现的接口来看,ArrayList支持clone,序列化,随机访问。在类中维持了两个成员变量:数组
int size; transient Object[] array;
其中size是ArrayList的长度,array是一个object类型的数组用于存储数据元素,元素自己也能够为null。等等,这里为何事transient来修饰的呢?说好的序列化呢?框架
原来,ArrayList并无使用默认的序列化机制,而是实现了readObject
和 writeObject 方法来完成序列化工做:
dom
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(); } }
这种方法比默认的机制更为高效,它并未存储整个数组中的null,这样节省了不少空间。学习
解释完序列化的疑问,咱们来看一下它的动态增加机制,在add方法中:spa
public boolean add(E object) { Object[] a = array; int s = size; if (s == a.length) { 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; }
咱们能够看到,当数组容量不足对数组扩容的时候,有一个判断:当前长度是不是最小增加长度(MIN_CAPACITY_INCREMENT 12)的1/2,若是小于则按最小增加长度进行扩容,不然扩容为当前容量的3/2.code
以上即是ArrayList源码学习中须要注意的两个疑问。blog