ArrayList是java中最常使用的動態數組,其具體使用方式就不再介紹,本文只是從源碼角度介紹它內部的序列化和擴容機制。ArrayList作為集合框架中的一員,它的繼承關系如下所示:

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 方法來完成序列化工作:
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方法中:
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.
以上便是ArrayList源碼學習中需要注意的兩個疑問。
新聞熱點
疑難解答