Java_ArrayList的工作原理

Resizable-array implementation of the List interface.  Implements
all optional list operations, and permits all elements, including
null.  In addition to implementing the List interface, this class provides methods to manipulate the size of the array that is used internally to store the list.  (This class is roughly equivalent to Vector, except that it is unsynchronized.)

ArrayList實現了List接口,能夠允許添加null,其本質是一個可以擴容的數組,與Vector不同僅僅在於它不是線程安全的。

看下面一個簡單的例子:
public class TestArrayList {
    public static void main(String[] args) {
           List<String> list=new ArrayList<String>();
           list.add("1");
           list.add("2");
           list.add("3");
           list.add("4");
           list.add("5");
           list.add("6");
           list.add("7");
           list.add("8");
           list.add("9");
           list.add("10");
           list.add("11");
           list.add("12");
           list.remove("bbb");       
     }
}

當只添加三個元素的時候:
這裏寫圖片描述
當添加超過10個元素的時候:
這裏寫圖片描述
可以看到這裏數組擴容到了10+10*1/2=15;


ArrayList部分源碼如下:(jdk1.8)

創建的時候:

 //new ArrayList的時候,如果傳入的參數,即初始化容量initialCapacity
 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() {
        //創建一個空的list
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }  

添加元素的時候:

 public boolean add(E e) {
        //檢查在添加一個元素的時候是否需要擴容
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }


 private void ensureCapacityInternal(int minCapacity) {
        //數組爲空的時候
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            //數組容量取DEFAULT_CAPACITY與minCapacity最大值
            //如果創建list的時候,沒有指定容量大小,這裏取DEFAULT_CAPACITY的大小10
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
   }

    private void ensureExplicitCapacity(int minCapacity) {
        //操作的次數+1
        modCount++;
        // overflow-conscious code
        //添加一個元素後比數組的長度大,則進行擴容處理
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
    //擴容操作
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        //新數組的長度爲原數組的1.5倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);

        if (newCapacity - minCapacity < 0)
            //擴容後的數組比需要的數組容量還是小,這裏主要指在創建ArrayList的時候指定的數組容量的大小,則直接把數組的容量擴充到所需大小
            newCapacity = minCapacity;
        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);
    }

get操作

 public E get(int index) {
        //檢查是否越界
        rangeCheck(index);
        return elementData(index);
    }

總結:
Arraylist在沒有自己初始化容量大小的時候,會創建一個默認大小爲10的數組,當數組元素的添加大於10的時候,會進行擴容處理,擴容後的大小爲原數組的1.5倍,然後把元素複製到新的數組中,這也就是可變數組的機制。一般在事先知道數組大小爲多少的時候,儘量自己手動的指定數組的大小,因爲數組的不斷擴容是會降低性能的。

發佈了76 篇原創文章 · 獲贊 48 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章