当前位置: 首页 > news >正文

集合篇之ArrayList

一、源码如何分析?

1.成员变量

2.构造方法

3.关键方法

        一些添加的方法。

二、debug看源码

我们给出下面代码:

    public void test01() {ArrayList<Integer> list = new ArrayList<>();list.add(1);for (int i = 2; i <= 10; i++) {list.add(i);}list.add(11);}

1.第一次添加数据

1. 添加方法:

2. 确保内部容量:

3. 计算容量:

4. 确保真正的容量:

5. 扩容的方法:

围绕着这5个方法进行讲解:

        首先,add()方法里面先执行ensureCapacityInternal(size + 1); 这里的size是0,因为数组是空的,所以传入到ensureCapacityInternal()方法的参数就是minCapacity == 1

        其次,我们就需要计算容量,在calculateCapacity()方法中,里面的传入的两个参数,其中第一个参数elementData的值,在ArrayList() 构造方法里面已经赋过值了,就是DEFAULTCAPACITY_EMPTY_ELEMENTDATA,第二个参数就是前面的 1 。所以if里面判断正确,返回最大值,其中DEFAULT_CAPACITY = 10,所以10>1,最后返回的也就是10

        然后,我们在ensureExplicitCapacity()中这个方法,传入的minCapacity这个参数也就是 10。因为在if判断中,条件成立,也就是说容量不够,需要扩容了。

        最后,进入grow()方法,其中因为oldCapacity=0,newCapacity计算得出也是0。第一个条件判断就是0-10<0,所以把10赋值给newCapacity,第二个是数组容量最大的安全校验(暂时不用),最后一行代码也就是数组的拷贝,把elementData的容量变成了 10 。

        这样,我们的数组第一次扩容就这样说完了,我们回到add方法,elementData[size++] = e,这行代码就是把下标为0的位置给了元素1,然后size+1,说明数组有一个元素了。

2.第二次添加数据

        我们第二次添加是用for循环,添加了9个元素,我们分析这个过程。

        首先,for循环添加第一个元素的时候,ensureCapacityInternal(size + 1); 这里的size是1,因为数组之前添加了一个元素进行了size++,所以传入到ensureCapacityInternal()方法的参数就是minCapacity == 2。

        其次,在计算容量的时候,elementData已经不是默认的了,所以直接返回minCapacity。

        然后,我们在ensureExplicitCapacity()中这个方法里面,在if判断里面,其中minCapacity是等于2的,elementData.length在第一次添加数据的时候,已经扩容为10了,所以2-10<0,不需要扩容了。在代码里面,for循环添加了9个元素,执行流程都一样。

        最后,在add方法里面,把数据添加到数组后进行size+1。

3.第三次添加数据

        我们第三次添加一个元素,其中数组已经有10个元素了,我们分析这个过程。

        首先,ensureCapacityInternal(size + 1); 这里的size是10,因为数组里面有了10个元素,所以传入到ensureCapacityInternal()方法的参数就是minCapacity == 11。

        其次,在计算容量的时候,elementData已经不是默认的了,所以直接返回minCapacity。

        然后,我们在ensureExplicitCapacity()中这个方法,传入的minCapacity这个参数也就是 11。因为在if判断中,条件成立11-10>0,也就是说容量不够,需要扩容了。

        最后,进入grow()方法,其中因为oldCapacity=10, oldCapacity >> 1也就是右移一位也就是5,newCapacity计算得出是15。第一个条件判断就是15-10>0,直接走过该判断,最后一行代码也就是数组的拷贝,把elementData的容量变成了 15 。

         这样,我们的数组扩容就完成了。

三、面试题

1. ArrayList底层的实现原理是什么?

  • 底层数据结构

ArrayList底层是用动态的数组实现的

  • 初始容量

ArrayList初始容量为0,当第一次添加数据的时候才会初始化容量为10

  • 扩容逻辑

ArrayList在进行扩容的时候是原来容量的1.5倍,每次扩容都需要拷贝数组

  • 添加逻辑

    • 确保数组已使用长度(size)加1之后足够存下下一个数据

    • 计算数组的容量,如果当前数组已使用长度+1后的大于当前的数组长度,则调用grow方法扩容(原来的1.5倍)

    • 确保新增的数据有地方存储之后,则将新元素添加到位于size的位置上。

    • 返回添加成功布尔值。

2.  ArrayList list=new ArrayList(10)中的list扩容几次?

该语句只是声明和实例了一个 ArrayList,指定了容量为 10,未扩容。

相关文章:

  • 【软件测试】--功能测试4-html介绍
  • untiy 室内灯光最佳实践
  • 爬取博客的图片并且将它存储到响应的目录
  • C#高级:DataGridView的详解
  • 练习2-线性回归迭代(李沐函数简要解析)
  • 命令行启动mongodb服务器的问题及解决方案 -- Unrecognized option: storage.journal
  • springboot 实现本地文件存储
  • SD NAND:为车载显示器注入智能与安全的心脏
  • selenium测试工具用来模拟用户浏览器的操作
  • MySQL常见面试题总结
  • Node.js基础---Express中间件
  • 利用 lxml 库的XPath()方法在网页中快速查找元素
  • kvm虚拟机修改网络模式
  • MySQL进阶之(三)InnoDB数据存储结构之数据页结构
  • SpringBoot源码解读与原理分析(三十八)SpringBoot整合WebFlux(一)WebFlux的自动装配
  • ----------
  • [Vue CLI 3] 配置解析之 css.extract
  • 【跃迁之路】【585天】程序员高效学习方法论探索系列(实验阶段342-2018.09.13)...
  • 〔开发系列〕一次关于小程序开发的深度总结
  • Android交互
  • Hexo+码云+git快速搭建免费的静态Blog
  • java8 Stream Pipelines 浅析
  • JavaScript设计模式系列一:工厂模式
  • jquery cookie
  • JS+CSS实现数字滚动
  • Redux系列x:源码分析
  • SpringCloud(第 039 篇)链接Mysql数据库,通过JpaRepository编写数据库访问
  • win10下安装mysql5.7
  • WinRAR存在严重的安全漏洞影响5亿用户
  • 关于List、List?、ListObject的区别
  • 前端_面试
  • 前端每日实战:70# 视频演示如何用纯 CSS 创作一只徘徊的果冻怪兽
  • 前端学习笔记之观察者模式
  • 前端自动化解决方案
  • 浅谈Kotlin实战篇之自定义View图片圆角简单应用(一)
  • 用jquery写贪吃蛇
  • 【运维趟坑回忆录 开篇】初入初创, 一脸懵
  • ​2021半年盘点,不想你错过的重磅新书
  • ​软考-高级-信息系统项目管理师教程 第四版【第23章-组织通用管理-思维导图】​
  • #LLM入门|Prompt#2.3_对查询任务进行分类|意图分析_Classification
  • $.each()与$(selector).each()
  • (01)ORB-SLAM2源码无死角解析-(56) 闭环线程→计算Sim3:理论推导(1)求解s,t
  • (16)UiBot:智能化软件机器人(以头歌抓取课程数据为例)
  • (十八)用JAVA编写MP3解码器——迷你播放器
  • (四)linux文件内容查看
  • .Net - 类的介绍
  • .NET Core 控制台程序读 appsettings.json 、注依赖、配日志、设 IOptions
  • .net core 连接数据库,通过数据库生成Modell
  • .net Stream篇(六)
  • .NET 同步与异步 之 原子操作和自旋锁(Interlocked、SpinLock)(九)
  • .NET 中什么样的类是可使用 await 异步等待的?
  • .Net语言中的StringBuilder:入门到精通
  • .ui文件相关
  • ?php echo ?,?php echo Hello world!;?
  • @requestBody写与不写的情况