1. 程式人生 > >ArrayList 源碼(基於Java1.8)

ArrayList 源碼(基於Java1.8)

dex extends code ray ati 沒有 cloneabl 刪除 class

ArrayList 基於數組實現,也就是類對變量 Object[]系列操作,封裝為常用的add,remove,indexOf, contains本質是通過 size 計數器對數組進行系列的操作實現

add 方法和 toArray 也是借助 Arrays 工具類完成

還有很有意思的地方就是add的擴容方法 ensureCapacityInternal() 就會增加50%容量,

因為底層數組是不可變的,所以add實際上是通過Arrays工具再拷貝擴容後長度的數組,然後覆蓋當前數組

預設集合長度是最優的操作,今天看源碼才明白原理,ArrayList默認構造器為內部數組定義的長度為10,當list超出指定集合的時候,ArrayList會操作自動擴容,

擴容的方法是使用Arrays.copyOf方法重新構造新的數組,然後將舊數組的數據全部拷貝到新的數組裏面,重新生成,再拷貝數組,消耗是巨大的,這也導致了 ArrayList 天生的缺點,插入刪除元素慢

技術分享
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {

    private static final long serialVersionUID = 8683452581122892189L;

    private static final int DEFAULT_CAPACITY = 10;

    private static final Object[] EMPTY_ELEMENTDATA = {};

    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    transient Object[] elementData; // non-private to simplify nested class access

    private int size;
技術分享

源碼中可以看到,ArrayList繼承抽象類AbstractList,實現List接口,RandomAccess, Cloneable, Serializable等接口主要用於標識,並沒有很大作用

DEFAULT_CAPACITY = 10 是集合的默認初始化長度,我們常用new ArrayList<>()構造,其實就是創建一個長度為10的Object[]數組

size 為計數器,記錄當前數組的長度

技術分享
public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }

    /**
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

ArrayList 源碼(基於Java1.8)