集合5,分析ArrayList源码

22 篇文章 2 订阅
本文深入剖析了ArrayList的源码,详细解释了其内部数据结构以及扩容策略。ArrayList在创建时,默认容量为0,首次添加元素时扩容至10,后续扩容为原容量的1.5倍。通过Arraycopyof机制实现数据迁移,确保原有元素不丢失。文章还对比了使用无参构造器和指定大小构造器的不同扩容行为,并探讨了这些设计对性能的影响。
摘要由CSDN通过智能技术生成

分析ArrayList源码

先说结论,下面是源码分析

  • Array List中维护了一个Object类型的数组,elementData[deBug看源码上看的很清楚]
  • 当创建ArrayList对象时,如果使用的是无参构造器,则初识elementData容量为 0,第一次添加则扩容elementData容量为10,如果需要再扩容,则扩容elementData为原先的1.5倍
  • 如果使用的数指定大小的构造器,则初始大小为elementData的指定大小,如果需要继续扩容则,则直接扩容elementData为1.5倍

分析使用无参构造器的创建和使用ArrayList的源码

  • 底层创建了一个空的 elementDATA数组

在这里插入图片描述

  • 执行list.add()方法,
    • 第一步先判断数组的容量是否足够我再添加一个,
    • 第二步才将我们传入的对象传入,完成赋值的操作,

在这里插入图片描述

  • 追入ensureCapacityInternal方法,该方法确定mincapacity

    • minCapacity指的是源数组中存储的元素个数加上将要存储的元素个数,这里第一次add()时,minCapacity为1,数组的长度为0,数组内存不够,故,进行扩充

    • 当最小容量减去刚创建时的容量(0),时大于0,则进行第一次扩容,扩容量为10

    • if语句是判断是否需要进行扩容的语句,注意:虽然每次循环都会进行检测是否需要扩容,但并不是每次都会进行扩容,只有elementData不够时(也就说明容量不足时)才会进行扩容。

在这里插入图片描述

  • grow()方法扩容的机制

    • 注意:扩容使用的是 Array copyof( )机制,也就是说在扩容时,会保留原本的数据

    • 第一次扩容比较特别,第一次为10,

    • 之后都是oldCapacity + (oldCapacity >> 1),也就是oldCapacity 的1.5倍扩容

    • int oldCapacity = elementData.length;
      //先将第一次数组大小(0)赋给oldCapacity
      //所以下方第一次判断{if (newCapacity - minCapacity < 0)}时就能,
      //将minCapacity(10)的容量赋给oldCapacity
      
      
      int newCapacity = oldCapacity + (oldCapacity >> 1);
      //它的意思是原先数组的大小,加上原先数组的大小/2,变为新的数组newCapacity 的大小
      //因为第一次扩容为10,所以就是10+10/2,也就是10的1.5倍
      //>>位运算符,对正数来说相当于除以2
      

在这里插入图片描述

  • 扩容后的空间示意
    • 扩容后多出来的空间就是用null表示

在这里插入图片描述

如果是有参构造

  1. 第一次扩容,就按照elementData的1.5倍扩容
  2. 整个执行流程还是和前面的一样的。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

玥骋

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

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

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

打赏作者

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

抵扣说明:

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

余额充值