Java面试中会问到ArrayList的每次扩容的大小.以前只是知道.并不知道代码具体实现.今天看了一下源码.记录一下.以便于以后查看
在1.6.x版中
public void ensureCapacity(int minCapacity) {
modCount++;
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
int newCapacity = (oldCapacity * 3)/2 + 1; //容量为50%+1
if (newCapacity < minCapacity)
newCapacity = minCapacity;
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
}
可以看到容量增加为原来的50%+1
在1.7.x版本中
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1); //容量为50%
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);
}
可以看到容量增加为原来的50%.并且在1.7.x版本中使用延迟分配数组大小.只有首次调用add方法的时候,才会分配内存.1.6版本中只要用默认构造函数创建一个对象,就会分配容量为10的数组.看一下源码的对比
1.6.x版本
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
}
public ArrayList() {
this(10); // 当创建对象时候,默认分配容量为10的数组
}
1.7.x版本
private static final Object[] EMPTY_ELEMENTDATA = {};
private static final int DEFAULT_CAPACITY = 10;
public ArrayList() {
super();
this.elementData = EMPTY_ELEMENTDATA; // 当创建对象时候,默认分配容量为0的数组
}
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); //当第一次调用add方法,才会分配容量为10的数组
}
ensureExplicitCapacity(minCapacity);
}
我们用代码测试一下
public class Test {
public static void main(String[] args) throws Exception {
List<Object> list = new ArrayList<Object>();
getLength(list);
list.add(new Object());
getLength(list);
list.add(new Object());
list.add(new Object());
list.add(new Object());
list.add(new Object());
list.add(new Object());
list.add(new Object());
list.add(new Object());
list.add(new Object());
list.add(new Object());
list.add(new Object());
getLength(list);
}
static void getLength(Object obj) throws Exception{
if (obj instanceof List) {
List list = (List) obj;
Field f = list.getClass().getDeclaredField("elementData");
f.setAccessible(true);
Object[] value = (Object[]) f.get(obj);
System.out.println("数组长度:"+value.length);
}
}
}
在1.6.x的版本中输出的结果
数组长度为:10
数组长度为:10
数组长度为:16
在1.7.x的版本中输出的结果
数组长度为:0
数组长度为:10
数组长度为:15