ArrayList的初始容量是多少?
很多人给出的答案是10
最近无意中又看了下ArrayList源码,发现江山已不再啊,很多时候面试自我感觉还不错,总被淘汰呢,也有这方面的原因,自不知了
源码出自JDK8版本,追溯了一下,JDK7高版本时代就开始变了
先定义了几个变量
/** * Default initial capacity. */ private static final int DEFAULT_CAPACITY = 10; /** * Shared empty array instance used for empty instances. */ private static final Object[] EMPTY_ELEMENTDATA = {}; /** * Shared empty array instance used for default sized empty instances. We * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when * first element is added. */ private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
从变量注释看,初始容量应该还是10,但看了下构造函数,发现记忆中的代码已经不见了
/** * Constructs an empty list with the specified initial capacity. * * @param initialCapacity the initial capacity of the list * @throws IllegalArgumentException if the specified initial capacity * is negative */ public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } } /** * Constructs an empty list with an initial capacity of ten. */ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
在没有指定初始容量时,但没有像JDK6时代一样,调用this(10)了,而只是赋值空数组
既然没有初始化时没有指定容量,在添加元素时不得溢出吗?
再看一下add()
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } private void ensureCapacityInternal(int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); } private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } 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); }
这几个方法可以看出:
- 在第一次add时,才去扩容,也就是懒式
- 每次扩容大小为oldCapacity + (oldCapacity >> 1),也就是1.5倍
到此回到问题本身:ArrayList的初始容量是多大呢?
不能直接说是0,更不能说是10
应该把这种优化过程说完整,以防与面试官的知识圈不匹配
在JDK6时,初始容量是10,但从JDK7开始,初始容量是0,会在第一次add元素时,扩容为10