Java的ArrayList(面试必须了解)——分析源码里的扩容机制(代码示例+图文)

面试可能会聊到ArrayList的扩容机制:首次分配大小为10的一个容量,超过10的容量那么就会以1.5倍扩容

举个通俗的例子:你是个老板,最开始你有5个员工分别要住5个房间,ArrayList很大方,首次就直接分配10个房间给你。后来你的事业蒸蒸日上,你的员工越来越多,有11个员工了,住不下原来的10个房间,那么我ArrayList以原来已经住的房间(10个的房间)的1.5倍方式开房间给你员工住。

结合上面列子和下面的图,可能会让你更加深理解
在这里插入图片描述
(原来10个房间 × 1.5 = 15房间,15个房间 × 1.5 = 22房间)

代码实例

首先创建一个ArrayList,调用add,然后点击add方法里面的源码看看究竟吧!

ArrayList<String> arraylist = new ArrayList<String>();
arraylist.add("hello");

可以看到add的一个函数,它先调用ensureCapacityInternal,是不是不知道它是干啥的,从字面意思理解的话是确保容量足够的,再点击看它的源码

    public boolean add(E e) {
        ensureCapacityInternal(size + 1); 
        elementData[size++] = e;
        return true;
    }

嗯…我去,又调了一个ensureExplicitCapacity,还有calculateCapacity,那就先看看
calculateCapacity

private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
 }

它会判断数组是否为空,如果为空,首次分配容量的值为10,它的常量:DEFAULT_CAPACITY = 10(这里确保容量足够)

private static int calculateCapacity(Object[] elementData, int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
       return Math.max(DEFAULT_CAPACITY, minCapacity);
      }
      return minCapacity;
    }

接下来调用ensureExplicitCapacity,判断当数据大于当前数组,那么调用grow

private void ensureExplicitCapacity(int minCapacity) {
        modCount++;
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

实现扩容的方法正是:grow

主要gorw方法里这句,oldCapacity右移1(相当于除以2),再加上oldCapacity(可以理解就是1.5倍)赋值给newCapacity。如果扩展还是小于minCapacity,就扩展minCapacity

int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity -minCapacity < 0)
newCapacity = minCapacity;
在这里插入图片描述

最后

你会发现看源码有点像剥洋葱,一层层的剥,不知道到什么时候你已经泪流满面了,当然只是个ArrayList还不至于啦

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值