java容器-List

add()方法

没有初始化容器数组长度大小的情况

 List<Integer> list = new ArrayList<>();
 
 list.add(1);

1.没有初始化list指定容量,我们可以看到初始化一个elementData 空数组。
2.add操作添加第一个元素,首先执行ensureCapacityInternal方法,minCapacity此时等于1,然后调用ensureExplicitCapacity方法,在执行这一步时候内部又进行了一个计算,调用方法calculateCapacity,参数1为数组对象elementData,参数2为minCapacity等于1.
3.calculateCapacity方法内部,先判断如果elementData 等于DEFAULTCAPACITY_EMPTY_ELEMENTDATA,返回DEFAULT_CAPACITYminCapacity三元运算的值。DEFAULT_CAPACITY=10,minCapacity=1.所以Math.max(DEFAULT_CAPACITY, minCapacity)返回10;
4.调用
ensureExplicitCapacity(10)
,如果 minCapacity - elementData.length > 0进入grow()
5.grow()方法,如果newCapacity - minCapacity < 0成立, newCapacity = minCapacity;,那么newCapacity 就等于10;然后
经过elementData = Arrays.copyOf(elementData, newCapacity); 最后elementData 数组长度被赋值为10。

源码


  transient Object[] elementData; 
  
  private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
  
  public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }


  public boolean add(E e) {
        
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
     private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    } 
    
    private static int calculateCapacity(Object[] elementData, int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }
    
   private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
    
   private void grow(int minCapacity) {
 
    int oldCapacity = elementData.length;// =0
    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);
    }

所以在初始化不指定容量的时候,添加第一个元素的时候,会默认数组长度为10;

当添加第11个元素的时候,此时minCapacity=11oldCapacity =10,此时
int newCapacity = oldCapacity + (oldCapacity >> 1);
首先10>>1,是右移一位 ,10转为二进制0000 1010 右移1位 0000 0101 转成10进制等于5,所以newCapacity 此时就等于15;
newCapacity - minCapacity<0不成立,newCapacity - MAX_ARRAY_SIZE > 0也不成立,直接到 elementData = Arrays.copyOf(elementData, newCapacity);这一步,新的数组长度就是15

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

所以第一次扩容后数组的长度为15

那么在添加第16个元素的时候,又要进入第二次扩容了,每次都是老的容量进行位运算,右移一位所以第二次扩容后数组的长度为22,在添加第23个元素,那么进行扩容后的长度就是22+22>>1等于33.。每次扩容后都是老容量的1.5倍大小。
核心代码就是下面这一行代码。int newCapacity = oldCapacity + (oldCapacity >> 1);

曾经面试碰到过一个题目

List<Integer> list = new ArrayList<>(20);经历几次扩容?

答案是0

在这里插入图片描述

在这里插入图片描述

所以得出另外一个结论,采用有参构造,如果是初始化容器数组长度为给定值的时候,必须要大于给定值才会扩容。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值