20220929-ArrayList扩容机制源码分析
示例代码
public class ArrayListSource {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList(); //跳转至第一步
for (int i = 0; i < 10; i++) {
arrayList.add(i); //需要进行第一次扩容,跳转至第二步
}
for (int i = 11; i <= 15; i++) {
arrayList.add(i); //需要进行第二次扩容
}
arrayList.add(100); //需要进行第三次扩容
arrayList.add(200);
arrayList.add(300);
}
}
代码分析
第一步:
当使用new ArrayList()创建集合时,会调用ArrayList类的无参构造器,在集合内部存在一个空的elementData数组,代码如下
private static final int DEFAULT_CAPACITY = 10; //默认容量
...
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; //默认空数组
...
transient Object[] elementData; //存放Object对象的数组
...
private int size; //集合中所包含的元素,默认为0
...
protected transient int modCount = 0;
...
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; //MAX_ARRAY_SIZE = 2147483639
...
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; //elementData初始化为{}数组,其中size=0
}
第二步:
程序进入for循环,从i=0开始,执行arrayList.add(i)方法,进入ArrayList类中
public boolean add(E e) { //此时:e=1
ensureCapacityInternal(size + 1); //跳转至第三步
elementData[size++] = e;
return true;
}
第三步:
执行ensureCapacityInternal(size + 1),其中size=0
private void ensureCapacityInternal(int minCapacity) { //此时minCapacity=size+1=1,即给集合中添加1个元素,需要的最小容量是1
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); //跳转至第四步
}
第四步:
先执行ensureExplicitCapacity()中的嵌套函数calculateCapacity(elementData, minCapacity)
// elementData = {}
// minCapacity = 1
// DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}
// DEFAULT_CAPACITY = 10
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { //此if语句成立
return Math.max(DEFAULT_CAPACITY, minCapacity); //返回值为10,退出函数,跳转至第五步,
}
return minCapacity;
}
第五步:
执行ensureExplicitCapacity()函数
// minCapacity = 10
// modCount默认为0,然后自加1
// elementData.length = 0
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
if (minCapacity - elementData.length > 0) //此时if语句成立
grow(minCapacity); //跳转至第六步
}
第六步:
执行grow(minCapacity)
// minCapacity = 10
// MAX_ARRAY_SIZE = 2147483639
private void grow(int minCapacity) {
int oldCapacity = elementData.length; //oldCapacity=0
int newCapacity = oldCapacity + (oldCapacity >> 1); //newCapacity=0+0/2=0
if (newCapacity - minCapacity < 0) //此if语句成立
newCapacity = minCapacity; //newCapacity = 10
if (newCapacity - MAX_ARRAY_SIZE > 0) //此if语句不成立
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
//此语句执行后,elementData = {null,null,null,null,null,null,null,null,null,null}
}
第七步:
当程序执行完第六步之后,根据方法调用步骤依次返回,直至第二步的第2条程序语句
public boolean add(E e) {//此时:e=1
ensureCapacityInternal(size + 1);
//通过以上方法,确保集合中可以存放e对象
elementData[size++] = e;//此时size=0,之后自加1;e=1
//执行之后 elementData = {1,null,null,null,null,null,null,null,null,null}
return true;
}
第八步:
在for循环中,不断执行 arrayList.add(i)方法,直到for循环结束,以上步骤介绍了ArrayList第一次默认初始化之后存放元素的步骤和扩容机制,当集合中存放的对象达到容量10时,集合需要再次进行扩容。而接下来的每次扩容的容量=原来容量*1.5,即 0 --> 10 --> 15 --> 22 --> 33...
20220929-ArrayList扩容机制源码分析的更多相关文章
- JAVA ArrayList集合底层源码分析
目录 ArrayList集合 一.ArrayList的注意事项 二. ArrayList 的底层操作机制源码分析(重点,难点.) 1.JDK8.0 2.JDK11.0 ArrayList集合 一.Ar ...
- Android事件分发机制源码分析
Android事件分发机制源码分析 Android事件分发机制源码分析 Part1事件来源以及传递顺序 Activity分发事件源码 PhoneWindow分发事件源码 小结 Part2ViewGro ...
- ArrayList详解-源码分析
ArrayList详解-源码分析 1. 概述 在平时的开发中,用到最多的集合应该就是ArrayList了,本篇文章将结合源代码来学习ArrayList. ArrayList是基于数组实现的集合列表 支 ...
- Springboot学习04-默认错误页面加载机制源码分析
Springboot学习04-默认错误页面加载机制源码分析 前沿 希望通过本文的学习,对错误页面的加载机制有这更神的理解 正文 1-Springboot错误页面展示 2-Springboot默认错误处 ...
- ApplicationEvent事件机制源码分析
<spring扩展点之三:Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法,在spring启动后做些事情> <服务网关zu ...
- 2.8.2 并发下的ArrayList,以及源码分析
package 第二章.并发下的ArrayList; import java.util.ArrayList;import java.util.List; /** * Created by zzq on ...
- Android查缺补漏(View篇)--事件分发机制源码分析
在上一篇博文中分析了事件分发的流程及规则,本篇会从源码的角度更进一步理解事件分发机制的原理,如果对事件分发规则还不太清楚的童鞋,建议先看一下上一篇博文 <Android查缺补漏(View篇)-- ...
- ArrayList 和 LinkedList 源码分析
List 表示的就是线性表,是具有相同特性的数据元素的有限序列.它主要有两种存储结构,顺序存储和链式存储,分别对应着 ArrayList 和 LinkedList 的实现,接下来以 jdk7 代码为例 ...
- List中的ArrayList和LinkedList源码分析
List是在面试中经常会问的一点,在我们面试中知道的仅仅是List是单列集合Collection下的一个实现类, List的实现接口又有几个,一个是ArrayList,还有一个是LinkedLis ...
随机推荐
- 教你使用CANN将照片一键转换成卡通风格
摘要:这次是将AnimeGAN部署到Ascend 310,从而实现对自己想要图片的一键转换为我们想看到的卡通风格. 本文分享自华为云社区<[CANN训练营]CANN训练营_昇腾AI趣味应用实现A ...
- Minimax 社论
目录 题面 题解 代码 Reference 题面 LOJ #2537 / 洛谷 P5298 「PKUWC2018」Minimax 一棵有根二叉树 \(\mathcal T\) . 定义结点 \(x\) ...
- 丽泽普及2022交流赛day22 无社论
开始掉分模式 . T3 有人上费用流了???(id) 不用 TOC 了 . T1 暴力 T2 没看见 任意两圆不相交,gg 包含关系容易维护,特判相切 . 单调栈即可 T3 贪心 T4 神秘题
- PHP进阶玩法
1. 删除不必要的模块. PHP随带内置的PHP模块.它们对许多任务来说很有用,但是不是每个项目都需要它们.只要输入下面这个命令,就可以查看可用的PHP模块: # php - m 一旦你查看了列表, ...
- 云原生Devops 的实现方法
DevOps 是一个持续改善软件产品的过程,它通过极短的发布周期.全面自动化的集成和交付流水线,以及团队间的紧密协作来不断改善产品.DevOps 的目标是缩短将创意变成用户可以使用的产品的时间,并降低 ...
- cmd命令行工具
在windows下进行python开发,需要经常使用cmd命令行工具.打开命令行工具有很多种方法,最简单的就是win键+R键弹出运行窗口,然后输入cmd, 就会打开下面这样的窗口. 不同版本,可能配色 ...
- 论文解读(DropEdge)《DropEdge: Towards Deep Graph Convolutional Networks on Node Classification》
论文信息 论文标题:DropEdge: Towards Deep Graph Convolutional Networks on Node Classification论文作者:Yu Rong, We ...
- 用lambda表达式和std::function类模板改进泛型抽象工厂设计
- Apache DolphinScheduler之最美好的遇见
关于 Apache DolphinScheduler社区 Apache DolphinScheduler(incubator) 于17年在易观数科立项,19年3月开源, 19 年8月进入Apache ...
- Jmeter工具使用总结
Jmeter工具使用总结 目录 Jmeter函数总结 第一章 前言 第二章 常用函数的介绍 2.1. timeShift函数 2.2. time函数 2.3. groovy函数 第三章 常用用法 3. ...