ArrayList扩容原理,源码追踪(jdk8)

news2024/12/25 23:35:55

ArrayList 扩容原理

add方法(扩容机制jdk8)

写一个代码案例断点调试

package list;

import java.util.ArrayList;

/**
 * @author 兰舟千帆
 * @version 1.0
 * @date 2023/7/26 19:08
 * @Description 功能描述:案例断点查看ArrayList的源码(添加)
 */
public class ArrrayListOriginSee {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();//这里打一个断点
        for (int i = 1;i<=10;i++)
        {
            list.add(i);
        }
        for (int i =11;i<=15;i++)

        {
            list.add(i);
        }
        list.add(100);
        list.add(200);
        list.add(null);
    }
}

image-20230726203309097

  • 1 定义列表的时候没有指定初始化容量,那么就会默认调用它的无参构造器,这里初始化了数组,是一个空的数组

image-20230726203612036

可以看到这里是一个Object类型的数组,但是是一个空的。

image-20230726203818260

这里断点返回会回到这个初始化的方法这里,可以看到初始化列表为一个空的列表

image-20230726204635427

下面继续执行

  • 2 执行add方法来观察ArrayList的扩容机制

首先执行10次添加元素

image-20230726204818896

进入方法,来到这里,其实在真正添加元素之前会执行装箱的操作,也就是Integer 的ValueOf方法

image-20230726204928611

从这里我们可以看出 :

IntegerCache.low = -128
IntegerCache.high = 127
缓冲区cache是一个Integer类型的数组
也就是说:IntegerCache缓存区间为[-128,127]。所以,在调用Integer.valueOf(int i)方法进行自动装箱时假若i的值在[-128,127]区间则生成的Integer对象会被存入缓冲区。当再次对该值进行装箱时会先去缓冲区中获取;如果取到则返回,如果没有取到则创建包装类对象存入缓冲区并返回。

一个知识点

这里是Integer 的 ValueOf方法,可以将数据转化为包装类型

Integer number00 = Integer.valueOf(123);
     Integer number02 = Integer.valueOf(123);
     System.out.println(number00==number02);//true
//        Integer.valueOf将基本类型转变为包装类型的过程中会有一个缓存的机制,就是范围在[-127~128]会存放在缓存中,那么引用就是一样的
     Integer integer = Integer.valueOf(129);
     Integer integer1 = Integer.valueOf(129);//false 超过了128那么就会重新new 一个Integer的类型,也就是创建了一个新的对象
     System.out.println(integer==integer1); //false
     Integer integer2 = Integer.valueOf(-1);
     Integer integer3 = Integer.valueOf(-1);
     System.out.println(integer2==integer3);//true

  • 继续断点

    会回到原来的断点的位置一次,然后我们再次进去的时候就来到这里,可以看到这个方法是一直返回true的

    image-20230726210106545

    然后进入到这个方法,这个方法字面意思理解就是确认容量的操作,首先第一句判断肯定是符合的,因为我们调用无参的构造方法的时候就是这句话初始化的。

    image-20230726210227040

    image-20230726210803636

    所以这里这个最小的容量会被初始化为10

    下面还有一段代码进行传入将10这个值传入

    image-20230726210857198

    进去方法

    image-20230726210950334

    然后执行下面这个方法,肯定是要执行grow的,这个其实可以理解为第一次扩容

    image-20230726211058785

    然后进入grow方法

    image-20230726211204905

    运行

    image-20230726211932427

    image-20230726212058372

    ​ 运行到这里

    image-20230726211719326

    这里进行了一个数组拷贝的操作其实就是扩容了在首次添加元素的时候

    image-20230726212121104

    然后回到这里,这里进行了元素的赋值

    image-20230726212241614

    在idea中要想看到这个完整的扩容还需要这里操作下,就是断点调试后在这个variables这里进行右键选择这里

    image-20230726213026641

    image-20230726212925548

    没有出现扩容效果的话可以这样设置然后再断点

    然后再看

    image-20230726213252752

    这里效果就出来了,所以这里会到10容量首次

  • 3然后继续添加,我们找到边界10。

    image-20230726213517765

    然后继续添加,这里就是走到下一个for循环,走到这里

    image-20230726213723369

    min变11

    image-20230726213758224

    传入

    image-20230726213819703

    传入

    image-20230726213852578

    这里首先new变15,第一个if肯定是没有执行的,这样这个newCapcticy就是15了,最后到了那个数组拷贝

    image-20230726213936519

    说明一下这个huge,其实一般是不会走到这里的,我使者循环1了添加这么多元素,实在太卡了,所以如果添加这么多元素性能会大大降低。

    image-20230727091036473

    变15容量

    image-20230726214255243

    然后继续添加的话,可以看到这里满15以后再添加会继续扩容

    image-20230726214628017

    image-20230726214734859

    跟踪完毕

总结:一般我们是直接调用无参的构造方法的,初始化列表容量的。不会直接取去初始化容量。如果自己初始化容量的话,那么就会调用有参构造方法,按照我们传递的大小去初始化容量,而不是一开始一个空的列表。
别如我们给一个执行容量
在这里插入图片描述
我们后面还是会走这些方法,这些方法都要去判断,好这里进入了一个有参的方法
在这里插入图片描述
这里就初始化为15了
在这里插入图片描述
在这里插入图片描述

执行这个add方法里面肯定还会进行一次装箱的。这里是一样的。
在这里插入图片描述
然后进去这个方法
在这里插入图片描述
这里其实还是1
在这里插入图片描述
然而真正确认容量的我们还是得进去下面的方法。
在这里插入图片描述
这里逻辑是一样的,下面这个if是不成立的,所以不会再重写扩容。这里是一样的。
在这里插入图片描述
但是还是无参构造好吧,谁能预期自己要搞多少数据,自己传参还是多此一举。就这样吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/796274.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

西门子PLC仿真环境搭建及通信过程详解

随着工控及上位机的广泛应用&#xff0c;在学习过程中&#xff0c;很多时候&#xff0c;我们都需要软件和硬件的结合。本方案主要用于解决在学习过程中PLC硬件的需求&#xff0c;以西门子PLC为例&#xff0c;详细描述了基于TIA博途系列软件实现西门子PLC仿真环境的搭建过程&…

SpringBoot基础篇-在IDEA中隐藏文件或文件夹(超详细版)

正常创建一个SpringBoot项目有如下文件&#xff1a; 通常我们创建一个springboot项目时会自动生成一些暂时用不到的文件&#xff0c;稍许有些碍眼&#xff0c;对于喜爱项目结构整洁清晰的人更是十分别扭&#xff0c;但那些文件可能后面又会用到&#xff0c;所以这里给一个小技巧…

微信小程序 Page页面

新建页面只需要在app.json配置好路径&#xff0c;编译器自动新增了页面 项目首页&#xff0c;在app.json哪个页面是第一位&#xff0c;哪个页面就是小程序首页

C# OpenCvSharpe 二值化工具 阈值 自适应阈值 局部阈值 InRange

效果 阈值 自适应阈值 局部阈值 InRange 项目 VS2010.net4.0OpenCvSharper3 Demo下载

创建自己的docker python容器环境;支持新增python包并更新容器;离线打包、加载image

1、创建自己的docker python容器环境 参考&#xff1a;https://blog.csdn.net/weixin_42357472/article/details/118991485 首先写Dockfile&#xff0c;注意不要有txt等后缀 Dockfile # 使用 Python 3.9 镜像作为基础 FROM python:3.9# 设置工作目录 WORKDIR /app# 复制当前…

SAP创建会计凭证,用BAPI扩展字段方法:BAPI_ACC_DOCUMENT_POST

业务需求&#xff1a;和银行做一个接口&#xff0c;要通过银行流水产生会计凭证&#xff0c;会计凭证的事务码是F-02&#xff0c;查到了BAPI方法BAPI_ACC_DOCUMENT_POST。昨天测试发现&#xff0c;有一些参数在BAPI_ACC_DOCUMENT_POST的输入和表参数中根本没有&#xff0c;如记…

css实现步骤条中的横线

实现步骤中的横线&#xff0c;我们使用css中的after选择器&#xff0c;content写空&#xff0c;然后给这个范围设定一个绝对定位&#xff0c;相当于和它设置伪类选择的元素的位置&#xff0c;直接看代码&#xff1a; const commonStyle useMemo(() > ({fontSize: 30px}),[]…

【HCIA】14.WLAN基础与配置实现

WLAN的术语 基本服务集BSS 一个AP覆盖的范围在一个BSS相同的区域内&#xff0c;STA可以相互通信 基本服务集标识符BSSID 是无线网络的一个身份标识&#xff0c;用AP的MAC地址表示 服务集标识符SSID 无线网络的标识&#xff0c;用字符串表示 扩展服务集ESS 由多个使用相同的…

遥感数字图像处理实验教程(韦玉春)--部分实验问题回答

个人的学习思考&#xff0c;仅供参考。 目录 实验三、图像合成和显示增强 一、目的 二、要求 三、实验 实验五、图像变换 一、目的 二、要求 三、实验 实验六、图像滤波 一、目的 二、要求 三、实验 实验七、图像分割 一、目的 二、要求 三、实验 实验八、图…

【JavaScript】花点时间了解执行上下文

引言 当我们在浏览器中运行JavaScript代码时&#xff0c;浏览器会先创建一个全局执行上下文&#xff08;Global Execution Context&#xff09;&#xff0c;然后逐行解析和执行代码。 执行上下文是JavaScript中非常重要的概念&#xff0c;它决定了代码的执行顺序和作用域链等…

vue elemenet

日常开发当中&#xff0c;只使用vue是不够的&#xff0c;虽然提供给我们强大的功能&#xff0c;用的还是原生的html标签。 这可能就需要我们去关注前台美化展示的工作。 日常开发当中都是vue去配合前端的组件库&#xff0c;两个结合起来一起去开发。 知识点 Element Plus 介绍…

Qt应用开发(基础篇)——Button按钮

目录 一、前言 二&#xff1a;QAbstractButton 抽象按钮基类 三&#xff1a;QPushButton 普通按钮 四&#xff1a;QCommandLinkButton 链接按钮 五&#xff1a;QCheckBox 复选按钮 六&#xff1a;QRadioButton 单选按钮 七&#xff1a;QToolButton 工具按钮 一、前言 常…

一劳永逸的日报月报制作方法,还不快来get

许多政府机构、企业都会使用日报、月报来把握现有状况&#xff0c;比如说生产制造企业&#xff0c;需要通过日报来监控项目进度和生产数据。哪怕这些报表制作起来繁琐浪费、重复复杂&#xff0c;但是企业不得不通过日报对生产数据进行实时把控。 那么有没有一种办法或者工具&a…

Linux为何是软件开发专业人员的心头爱-Robotics Ubuntu

Linux与Windows都是十分常见的电脑操作系统&#xff0c;相信你对它们二者都有所了解&#xff01;在你的使用过程中&#xff0c;是否有什么事让你觉得在Linux上顺理成章&#xff0c;换到Windows上就令你费解&#xff1f;亦或者关于这二者你有任何想要分享的&#xff0c;都可以在…

幸福长寿的秘诀 —— 查理芒格

查理芒格&#xff1a;幸福长寿的秘诀其实很简单。_哔哩哔哩_bilibili People trying to figure out what the secret to life, is to a long and happy life ? Its simple. You dont have a lot of envy. You dont have a lot of resentment. You dont overspend your incom…

wms-3代货架标签系统(四个灯供电版本)接口文档

一、查询标签信息接口 接口类型&#xff1a;POST, 参数格式&#xff1a;json array 链接形式&#xff1a; http://localhost/wms/associate/getTagsMsg 代码形式&#xff1a; { url : http://localhost/wms/associate/getTagsMsg, requestMethed : GET, requestParamete…

Django模板语法和请求

1、在django关于模板文件加载顺序 创建的django项目下会有一个seeetings.py的文件 如果在seeetings.py 中加了 os.path.join(BASE_DIR,‘templates’)&#xff0c;如果是pycharm创建的django项目会加上&#xff0c;就会默认先去根目录找templates目录下的html文件&#xff0c…

CMIP6数据处理及在气候变化、水文、生态等领域中的实践技术应用

气候变化对农业、生态系统、社会经济以及人类的生存与发展具有深远影响&#xff0c;是当前全球关注的核心议题之一。IPCC&#xff08;Intergovernmental Panel on Climate Change&#xff0c;政府间气候变化专门委员会&#xff09;的第六次评估报告明确&#xff1b;指出&#x…

建议收藏:模拟版图面试题,含解析(附下载)

IC行业是一个充满竞争和机遇的领域&#xff0c;而作为一名模拟版图工程师&#xff0c;在面试中表现出色至关重要。 之前为大家全面解析过模拟版图&#xff0c;但面对面对即将找工作或者是面对今年秋招的的同学&#xff0c;可能对于模拟版图面试这块更感兴趣。 秋今天芯博士为…

Python数据可视化工具——Matplotlib

目录 1 基础准备1.1简介1.2安装1.3 绘图基础知识1.4 查询matplotlib系统中文字体 2 绘图流程2.1 简单绘图2.2 标准绘图2.3 绘制子图2.3.1 add_subplot方法两行一列子图 plt1.add_subplot(2,1,*)一行两列子图 plt1.add_subplot(1,2,*) 2.3.2 plt.subplot()方法 2.4 添加文字说明…