今天在看spring的源碼的時候,看到這麼一行代碼
List<String> beanDefinitionNames = new ArrayList<String>(64);
看來下這個list的定義:
java.util.ArrayList.ArrayList<String>(int initialCapacity)
最後才恍然大悟,原來我們的List是基於數組的一個集合,在每次修改List的長度的時候,其實底層都會重新生成一個新的數組
Arrays.copyOf(elementData, newCapacity);
我們的List在new的時候,會給一個默認的長度爲10的數組,ex:
List list = new ArrayList<String>();
list.add("1");
list:[1, null, null, null, null, null, null, null, null, null]
所以當我給list增加11個元素後,再來看下結果
List list = new ArrayList<String>();
list.add("1");
list.add("2");
...
list.add("11");
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, null, null, null, null]
然後我們在來看下jdk1.8的源碼,當調用list的add方法時,最後在計算數組長度的時候,會調用這麼一段方法:
private void grow(int minCapacity) {
// overflow-conscious code
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);
}
所以,看到grow方法的第二行,有一個位移算法,是用原來的長度加上長度的一半得到新的list的長度。
到此應該全部清楚了,如果我們不停的重新對list做長度增加時,其實還是有一定的佔用資源的。