Java源码解读:ArrayList扩容类型

了解Java咖啡的最好的方式就是从源码入手,因为源码是最真实的第一手资料,如果仅仅是阅读别人的公众号文章和博客解读,因为人非圣贤,总会出现理解偏差,故是相对较次的手段。本文帮助一些阅读上有困难的朋友对源码的基础上加以自身理解的注释,希望大家能喜欢。
ArrayList.add( )源码

public boolean add(E e) {
		// 确保有充足的空间可以容纳 新元素
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}

ArrayList.ensureCapacityInternal( )源码

// minCapacity 指的是至少需要的槽位长度
private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}


private void ensureExplicitCapacity(int minCapacity) {
		//The number of times this list has been <i>structurally modified</i>.
		//容器长度改变的次数
    modCount++;

    // overflow-conscious code
    // 如果需要的最小容器槽位数量大于当前元素长度,意味着根本容不下新元素
    //所以赶紧扩容吧!!!
    if (minCapacity - elementData.length > 0)
    		// 开始扩容!
        grow(minCapacity);
}

ArrayList.grow( ),这个函数才是真正的扩容过程,其中的要点是
1、盲目可以扩容1.5倍
2、确定1.5倍扩容是否合理

    /**
     * Increases the capacity to ensure that it can hold at least the
     * number of elements specified by the minimum capacity argument.
     *
     * @param minCapacity the desired minimum capacity
     */
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        //新的容量=旧的容量*1.5呗;至于位运算嘛,就是为了快。
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        // 扩容后的容量值还变的更小了?咋回事?
        // 我猜猜:minCapacity*1.5>Integer.MAX_VALUE会出现这种局面
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        //int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8
        //扩容后超过了允许的最大容量,说明1.5倍后扩容的已经不合理了。
        if (newCapacity - MAX_ARRAY_SIZE > 0)
        		//重新确定扩容后的容量,如何确定呢?
        		//1.需要最小容量minCapaCity<0,意味继而上一次扩容后,已经溢出int范围
        		//2.在minCapacity在 MAX_ARRAY_SIZE 与 Integer.MAX_VALUE 之间,则直接扩容					
        		//					newCapacity=Integet.MAX_VALUE。
        		//3.minCapacity <= MAX_ARRAY_SIZE则可以扩容到,
        		//	在前面一系列的操作下,不会出现minCapacity很小,newCapacity大到不合理的情况.
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:,
        // 扩容后用Arrays.copy,将数据转移到新的容器数组,并赋值给原引用。
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
    
    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }

理解有所偏差的话,望指正!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值