ArrayList扩容机制

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

粗略来说,ArrayList每次扩容1.5倍左右,为何呢?
正常情况下,ArrayList的扩容公式是:int newLength = Math.max(minGrowth, prefGrowth) + oldLength;其中perGrowth = oldGrowth >> 1,所以当oldGrowth 为奇数时,perGrowth就会略小于oldGrowth的0.5倍。

一、看一下源码,便一目了然

/*
如有必要,增加此 ArrayList 实例的容量,以确保它至少可以容纳最小容量参数指定的元素数。
参数:
最小容量 – 所需的最小容量
*/
public void ensureCapacity(int minCapacity) {
        if (minCapacity > elementData.length
            && !(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
                 && minCapacity <= DEFAULT_CAPACITY)) {
            modCount++;
            grow(minCapacity);
        }
    }
/*
增加容量以确保它至少可以容纳最小容量参数指定的元素数。
参数:
最小容量 – 所需的最小容量
抛出:
OutOfMemoryError – 如果最小容量小于零
*/
private Object[] grow(int minCapacity) {
        int oldCapacity = elementData.length;
        if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            int newCapacity = ArraysSupport.newLength(oldCapacity,
                    minCapacity - oldCapacity, /* minimum growth */
                    oldCapacity >> 1           /* preferred growth */);
            return elementData = Arrays.copyOf(elementData, newCapacity);
        } else {
            return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
        }
    }
/*
在给定阵列的当前长度、首选增长值和最小增长值的情况下计算新的阵列长度。如果首选增长值小于最小增长值,则使用最小增长值代替它。如果当前长度和首选增长值的总和不超过 MAX_ARRAY_LENGTH,则返回该总和。如果当前长度和最小增长值的总和不超过 MAX_ARRAY_LENGTH,则 MAX_ARRAY_LENGTH 返回。如果总和没有溢出 int,则 Integer.MAX_VALUE 返回。否则, OutOfMemoryError 被抛出。
参数:
oldLength – 数组的当前长度(必须为非负数)
最小增长 – 阵列长度所需的最小增长(必须为正数)
prefGrowth – 数组长度的首选增长(如果小于 minGrowth)
返回:
数组的新长度
抛出:
OutOfMemoryError – 如果通过 oldLength 溢出增加 minGrowth 。
*/
public static int newLength(int oldLength, int minGrowth, int prefGrowth) {
        // assert oldLength >= 0
        // assert minGrowth > 0

        int newLength = Math.max(minGrowth, prefGrowth) + oldLength;
        if (newLength - MAX_ARRAY_LENGTH <= 0) {
            return newLength;
        }
        return hugeLength(oldLength, minGrowth);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值