今天在看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做长度增加时,其实还是有一定的占用资源的。