ArrayList底層結構和原始碼分析

Dr丶云幕發表於2024-07-05
        // 無參構造器建立ArrayList物件
//        ArrayList list =new ArrayList();   // 斷點1
        ArrayList list =new ArrayList(8);   // 斷點2
        // 新增1-10資料
        for (int i = 0; i <= 10; i++) {
            list.add(i);
        }
        // 新增11-15資料
        for (int i = 11; i <= 15; i++) {
            list.add(i);
        }
        list.add(100);
        list.add(200);
  1. permits all element,including null,ArrayList 可以加入(多個)null,
  2. ArrayList是由陣列來實現儲存的
  3. ArrayList吧基本等於Vector,除了ArrayList是執行緒不安全(執行效率高)透過原始碼可以檢視到多執行緒不使用ArrayList。

ArrayList底層結構和原始碼分析

透過原始碼可以得知add方法沒有synchronized;即沒有執行緒安全控制。

  1. ArrayList中維護了一個Object型別的陣列elementData. transient(表示,“瞬間”,該屬性不會被序列化) Object[] elementsData;
  2. 當建立了ArrayList物件時,如果使用無參構造器,則初始化elementData容量為0,第一次新增,則擴容elementData為10,如需要再次擴容則擴容為1.5倍。
  3. 如果使用的是一個指定大小的構造器,則初始化elementData容量為指定大小,擴容為1.5倍(當前大小+當前大小/2)。

ArrayList底層結構和原始碼分析

建立了一個空的elementData陣列

ArrayList底層結構和原始碼分析

執行list.add新增資料,確定是否需要擴容。

ArrayList底層結構和原始碼分析

確定minCapacity(第一次擴容為10)

ArrayList底層結構和原始碼分析

if判斷elementData大小是否需要擴容

注意:idea在Debug是預設簡化顯示,需要完整顯示則需要設定

        // grow擴容原始碼
        //使用擴容機制確定擴容,首次newCapacity=10,往後每次按1.5倍擴容
        //擴容使用的是Arrays.copyOf()
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            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);

斷點2

ArrayList底層結構和原始碼分析

建立了一個指定大小的elementData陣列

如果是有引數的構造器沒擴容機制:

  1. 第一次擴容,按照elementData的1.5倍擴容。
  2. 執行流程同前。

相關文章