ArrayList扩容
ArrayList是如何扩容的,每次扩容都是“1.5倍”吗,一个例子带你了解扩容机制
1、ArrayList初始化容量为10个元素。
private static final int DEFAULT_CAPACITY = 10;
2、执行add方法时
-
计算容量不够时、会执行扩容方法,容量变成原先容量+原先容量右移1位。见例子len2
3、执行addAll方法时,会有两种情况,见例子len3
-
如果计算(原先容量+原先容量右移1位)后,容量还不满足需要的扩容量,则直接扩容到需要的扩容量 -
如果计算(原先容量+原先容量右移1位)后,容量满足需要的扩容量,则容量为计算出的容量
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); //现有的元素个数加上addAll元素的个数
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
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);
}
4、一个例子
public class ListMergeTest {
public static void main(String[] args) throws Exception {
Field f = ArrayList.class.getDeclaredField("elementData");
f.setAccessible(true);
List<String> l1 = new ArrayList<>();
String s1 = "hjhfjk";
for (int i = 0; i < 9; i++) {
l1.add(s1);
}
Object[] o1 = (Object[]) f.get(l1);
long len1 = (long) o1.length * (long) s1.getBytes().length;
List<String> l2 = new ArrayList<>();
String s2 = "hjhfjk";
for (int i = 0; i < 9; i++) {
l2.add(s2);
}
Object[] o2 = (Object[]) f.get(l2);
long len2 = (long) o2.length * (long) s2.getBytes().length;
List<String> l3 = new ArrayList<>();
l3.addAll(l1);
l3.addAll(l2);
Object[] o3 = (Object[]) f.get(l3);
long len3 = (long) o3.length * (long) s2.getBytes().length;
List<String> l4 = new ArrayList<>();
String s4 = "hjhfjk";
for (int i = 0; i < 18; i++) {
l4.add(s4);
}
Object[] o4 = (Object[]) f.get(l4);
long len4 = (long) o4.length * (long) s4.getBytes().length;
System.out.println(len1 + len2 + "--------" + len3 + "-------" + len4);
}
}