ArrayList源碼分析

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

 

image

 

 

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並無使用默認的序列化機制,而是實現了readObjectwriteObject 方法來完成序列化工做: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

相關文章
相關標籤/搜索