• ArrayList扩容分析


    一段java代码

    1 String e = "q3234v";
    2 List<String> list = new ArrayList<String>();
    3 for (int i = 0; i < 25; i++) {
    4     list.add(e);
    5 }

    执行这段代码,list会扩容几次

    查看ArrayList的add方法,在添加元素之前会执行ensureCapacityInternal方法

    这个时候size为0

    1   public boolean add(E e) {
    2         ensureCapacityInternal(size + 1);  // Increments modCount!!
    3         elementData[size++] = e;
    4         return true;
    5     }

    继续看ensureCapacityInternal方法,DEFAULT_CAPACITY的值为10,此时minCapacity为1

    private static final int DEFAULT_CAPACITY = 10;
    1 private void ensureCapacityInternal(int minCapacity) {
    2     if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
    3         minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    4     }
    5     ensureExplicitCapacity(minCapacity);
    6 }

    这时候执行:ensureExplicitCapacity

    此时minCapacity的值为10,接下来执行扩容方法

    1 private void ensureExplicitCapacity(int minCapacity) {
    2     modCount++;
    3     // overflow-conscious code
    4     if (minCapacity - elementData.length > 0)
    5         grow(minCapacity);
    6 }
     1  private void grow(int minCapacity) {
     2         // overflow-conscious code
     3         int oldCapacity = elementData.length;
     4         int newCapacity = oldCapacity + (oldCapacity >> 1);
     5         if (newCapacity - minCapacity < 0)
     6             newCapacity = minCapacity;
     7         if (newCapacity - MAX_ARRAY_SIZE > 0)
     8             newCapacity = hugeCapacity(minCapacity);
     9         // minCapacity is usually close to size, so this is a win:
    10         System.out.println(minCapacity+"------"+newCapacity);
    11 
    12         elementData = Arrays.copyOf(elementData, newCapacity);
    13 }

    minCapacity的值为10

    新空间大小的值为 0+0>>1 = 0

    所以第一次扩容完 后新空间大小为10

    接下当list.add()执行到第11次的时候

    minCapacity=11

    newCapacity = 10+10>>1 = 15(1010>>1 = 101= 5)

    i执行到16的时候,此时又发现空间不够了

    minCapacity=16

    newCapacity = 15+15>>1 = 22(1111>>1 = 7)

    所以容量到25还需要再执行一次扩容

    一共会执行4次扩容

    这时候可能会发现在扩容的时候会执行 elementData = Arrays.copyOf(elementData, newCapacity)方法

    所以为了减少copyOf的操作

    在大概知道List的长度的情况下,在创建的时候应该给一个容量,在容量不够的情况下才会执行扩容操作

     1 public ArrayList(int initialCapacity) {
     2         if (initialCapacity > 0) {
     3             this.elementData = new Object[initialCapacity];
     4         } else if (initialCapacity == 0) {
     5             this.elementData = EMPTY_ELEMENTDATA;
     6         } else {
     7             throw new IllegalArgumentException("Illegal Capacity: "+
     8                                                initialCapacity);
     9         }
    10     }
  • 相关阅读:
    【BZOJ-3712】Fiolki LCA + 倍增 (idea题)
    【BZOJ-1941】Hide and Seek KD-Tree
    【BZOJ-2400】Spoj839Optimal Marks 最小割 + DFS
    【BZOJ-3709】Bohater 贪心
    【BZOJ-2342】双倍回文 Manacher + 并查集
    【BZOJ-3790】神奇项链 Manacher + 树状数组(奇葩) + DP
    【BZOJ-4568】幸运数字 树链剖分 + 线性基合并
    【BZOJ-4520】K远点对 KD-Tree + 堆
    【BZOJ-4127】Abs 树链剖分 + 线段树 (有趣的姿势)
    【BZOJ-2648&2716】SJY摆棋子&天使玩偶 KD Tree
  • 原文地址:https://www.cnblogs.com/modprobe/p/4522448.html
Copyright © 2020-2023  润新知