ArrayList原始碼
空建構子
如果使用空的建構子,預設一開始的陣列大小是10。
1
List list = new ArrayList();
若之後增加超過10,會以1.5倍的方式增加容量。
Debug設定
要Debug ArrayList查看容量變化大小,要把以下勾勾取消。
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;
}
- 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);
確實集合的大小變成15,上圖11-14是null。