ArrayList原始碼

空建構子

如果使用空的建構子,預設一開始的陣列大小是10。

1
List list = new ArrayList();

若之後增加超過10,會以1.5倍的方式增加容量。

Debug設定

要Debug ArrayList查看容量變化大小,要把以下勾勾取消。

img

Debug ArrayList

空建構子

1.斷點設在下面程式碼第一行。
2.執行Debug
3.step into

1
2
3
4
List list = new ArrayList();
for (int i = 0; i < 10; i++) {
  list.add(i);
}

4.進入無參數建構子
5.step Out

1
2
3
public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

6.此時游標會停留在第一行,step over
7.此時游標會停留在第二行,step over
8.此時游標會停留在第三行,step into

1
2
3
4
List list = new ArrayList();
for (int i = 0; i < 10; i++) {
  list.add(i);
}

9.此時進入包裝類別的valueOf()方法,step out離開此方法。
10.此時游標會停留在第三行,沒有在下一行,代表還有方法沒執行完,step into方法。

1
2
3
4
5
public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

11.進到add方法,step over到下一行。 12.step into進到add(e, elementData, size);

1
2
3
4
5
public boolean add(E e) {
    modCount++;  // 集合被修改的次數,防止多執行緒同時修改
    add(e, elementData, size);
    return true;
}

13.s為0,elementData.length也為0,step into grow()方法。

1
2
3
4
5
6
private void add(E e, Object[] elementData, int s) {
    if (s == elementData.length)
        elementData = grow();
    elementData[s] = e;
    size = s + 1;
}
  1. oldCapacity為0,minCapacity為0,DEFAULT_CAPACITY為10, 執行new Object[10]
1
2
3
4
5
6
7
8
9
10
11
private Object[] grow(int minCapacity) {
    int oldCapacity = elementData.length;
    if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        int newCapacity = ArraysSupport.newLength(oldCapacity,
                minCapacity - oldCapacity, // minimum growth 
                oldCapacity >> 1           // preferred growth );
        return elementData = Arrays.copyOf(elementData, newCapacity);
    } else {
        return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
    }
}

15.一路step out離開方法。

第11個資料

斷點設在list.add(11);

1
2
3
4
5
6
    List list = new ArrayList();
    for (int i = 0; i < 10; i++) {
      list.add(i);
    }
    list.add(11);
    System.out.println(list);

一路step into到下面這個方法

1
2
3
4
5
6
7
8
9
10
11
12
13
    public static int newLength(int oldLength, int minGrowth, int prefGrowth) {
        // preconditions not checked because of inlining
        // assert oldLength >= 0
        // assert minGrowth > 0

        int prefLength = oldLength + Math.max(minGrowth, prefGrowth); // might overflow
        if (0 < prefLength && prefLength <= SOFT_MAX_ARRAY_LENGTH) {
            return prefLength;
        } else {
            // put code cold in a separate method
            return hugeLength(oldLength, minGrowth);
        }
    }

重點是以下這二行,oldCapacity為10,prefLength為10 + 5

1
2
oldCapacity >> 1 // 10除2 = 5
int prefLength = oldLength + Math.max(minGrowth, prefGrowth);

img

確實集合的大小變成15,上圖11-14是null。

results matching ""

    No results matching ""