1. 程式人生 > 實用技巧 >Vue+Ant design vue安裝及配置使用

Vue+Ant design vue安裝及配置使用

ArrayList原始碼分析

底層資料結構:Object型別陣列:Object[ ] elementData

一、JDK 7主體原始碼

步驟及其原始碼底層實現

1.建立一個ArrayList物件

ArrayList list = new ArrayList();	//底層建立了長度是10的Object[] 陣列elementData

底層實現ArrayList.java

private transient Object[] elementData;

第一步:呼叫無參構造器

    public ArrayList() {
        this.(initialCapacity:10);	//呼叫本類當中的過載構造器
    }

第二步:this.(initialCapacity:10);呼叫本類當中的過載構造器

    public ArrayList(int initialCapacity) {
        super();
        if(initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity]	//初始化陣列,容量為10
    }

2.新增資料,add()方法

list.add(1);
...
list.add(11);	//elementData[0] = new Integer(1)
				//如果此次的新增導致底層elementData陣列容量不夠,則擴容。
				//預設情況下,擴容為原來的容量的1.5倍,同時需要將原有陣列中的資料複製到新的陣列中

底層實現ArrayList.java

第一步:呼叫add( )

public boolean add(E e) {
        ensureCapacityInternal(size + 1);  //確認容量是否夠	size:代表已經添加了幾個,初次為0
        elementData[size++] = e;		   //新增操作
        return true;
    }

第二步:呼叫ensureCapacityInternal(),確認容量是否夠

private void ensureCapacityInternal(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)	//minCapacity即size + 1,elementData.length為10
            grow(minCapacity);						//擴容
    }
  • 擴容:當新增第11個元素時,size為10,size+1也就是minCapacity為11,此時if條件:minCapacity - elementData.length > 0

成立,於是呼叫grow()方法進行擴容。

grow()

private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;						//初始容量:10
        int newCapacity = oldCapacity + (oldCapacity >> 1);			//預設擴容為原來的1.5倍,第一次擴容為15
        ...
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

elementData = Arrays.copyOf(elementData, newCapacity);

原來容量為10的陣列elementData需要被重新賦值為容量為15的陣列,並且將原來的陣列元素複製到新陣列中

結論

建議開發中使用帶參構造器ArrayList arrayList = new ArrayList(int capacity);這樣可以避免擴容。

二、JDK 8中ArrayList的變化

1.建立一個ArrayList物件(沒有建立長度是10的Object[] 陣列)

ArrayList list = new ArrayList();	//底層Object[] elementData初始化為{},並沒有建立長度為10的陣列

底層實現ArrayList.java

public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;	//指定了一個常量
    }
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};	//這裡什麼都沒有 長度為0

這裡不像JDK 7那樣在建立物件時就將陣列例項化,從時間和佔用記憶體(節省)上來說,這種方式較好一些

2.新增資料,add()方法

list.add(1)	//第一次呼叫add()時,底層才建立了長度為10的陣列,並將資料1新增到elementData[0]
...

底層實現ArrayList.java

第一步:第一次呼叫add( )

public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

第二步:呼叫ensureCapacityInternal(),確認容量是否夠

0private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }

第三步:呼叫calculateCapacity()

private static int calculateCapacity(Object[] elementData, int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {	//第一次呼叫add()時,該條件成立
            return Math.max(DEFAULT_CAPACITY, minCapacity);		//預設容量DEFAULT_CAPACITY為10
        }														//minCapacity即size+1=1
        return minCapacity;										//10
    }

第四步:呼叫ensureExplicitCapacity()

private void ensureExplicitCapacity(int minCapacity) {
    modCount++;

    // overflow-conscious code
    if (minCapacity - elementData.length > 0)		//minCapacity:10	elementData.length:0
        grow(minCapacity);							//10
}

第五步:呼叫grow()

private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;						//0
    int newCapacity = oldCapacity + (oldCapacity >> 1);			//0=0+0
    if (newCapacity - minCapacity < 0)							//0-10<0
        newCapacity = minCapacity;								//newCapacity為10
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    // minCapacity is usually close to size, so this is a win:
    elementData = Arrays.copyOf(elementData, newCapacity);		//此時建立了長度為10的陣列
}

三、總結

ArrayList原始碼分析:

1.jdk 7

ArrayList list = new ArrayList();	
  1. 底層建立了長度是10的Object[] 陣列elementData。
list.add(1);
...
list.add(11);	//elementData[0] = new Integer(1)
  1. list.add(11); --->如果此次的新增導致底層elementData陣列容量不夠,則擴容。預設情況下,擴容為原來的容量的1.5倍,同時需要將原有陣列中的資料複製到新的陣列中

2.jdk 8中ArrayList的變化

ArrayList list = new ArrayList();
  1. 底層Object[] elementData初始化為{},並沒有建立長度為10的陣列
list.add(1)	
...
  1. 第一次呼叫add()時,底層才建立了長度為10的陣列,並將資料1新增到elementData[0]。
  • 後續的新增和擴容操作與jdk 7無異。
小結
jdk 7當中的ArrayList的物件的建立類似單例的餓漢式,而jdk 8中的ArrayList的物件的建立類似於單例的懶漢式,延遲了陣列的創
建,節省記憶體。