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