ArrayList扩容例子

120 阅读1分钟

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);
        }
    }

image.png