java8 对ArrayList底层扩容的查看

本文深入解析了ArrayList的add()方法及其内部的扩容机制。当数组容量不足时,ArrayList通过grow()方法进行扩容,通常按原容量的1.5倍进行扩展。在特定条件下,如初始容量为0,会创建一个容量为10的新数组。此外,文章还介绍了扩容过程中处理数组长度超过最大值的情况。
摘要由CSDN通过智能技术生成

首先我们来看add()方法

public boolean add(E e) {
        modCount++;//记录此列表被结构修改的次数
        add(e, elementData, size);//调用私有的add方法
        return true;
    }

它调用了另一个私有的方法

private void add(E e, Object[] elementData, int s) {
//如果size等于存储数组的长度,调用grow()方法进行扩容
        if (s == elementData.length)
            elementData = grow();

//运行到此一定是容量足够的,将传入的对象赋值给存储数组,并记录现有元素的数量
        elementData[s] = e;
        size = s + 1;
    }

那么我们再来看看grow()是怎么扩容的

private Object[] grow() {
//方法体内还调用了真正的扩容方法
        return grow(size + 1);
    }
 private Object[] grow(int minCapacity) {
        //minCapacity接收加入新元素后的size

        //oldCapacity接收了原存储数组的长度
        int oldCapacity = elementData.length;
        //private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
        //一开始创建的长度为0的存储数组

//如果不是第一次调用,则扩容,并将原有数据复制到新数组中,并赋值给原有栈变量,返回存储数组
        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);
        } 
//如果是第一次调用add方法,这时候会进入else,新建一个长度为10的数组并返回
        else {
            return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
        }
    }

获取新长度的方法,一般情况下是增加为原来的1.5倍

public static int newLength(int oldLength, int minGrowth, int prefGrowth) {
        // assert oldLength >= 0
        // assert minGrowth > 0
        //int prefGrowth首选增长值
        //int minGrowth最小增长值
        //int oldLength原长度

        int newLength = Math.max(minGrowth, prefGrowth) + oldLength;
        //如果新长度小于可以增加的最大长度,则直接返回这个新长度
        if (newLength - MAX_ARRAY_LENGTH <= 0) {
            return newLength;
        }
        //返回
        return hugeLength(oldLength, minGrowth);
    }
private static int hugeLength(int oldLength, int minGrowth) {
        int minLength = oldLength + minGrowth;
           
        if (minLength < 0) { // overflow
            throw new OutOfMemoryError("Required array length too large");
        }
//如果最小增长值小于等于这个最大长度MAX_ARRAY_LENGTH=MAX_VALUE-8
        if (minLength <= MAX_ARRAY_LENGTH) {
            return MAX_ARRAY_LENGTH;
        }
//否则返回能表示的最大值
//public static final int   MAX_VALUE = 0x7fffffff;
        return Integer.MAX_VALUE;
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孔雀南飞梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值