ArrayList学习

1.2.1 构造方法
方法名说明
public ArrayList()创建一个空的集合对象
1.2.2 成员方法
方法名说明
public boolean add(E e)将指定的元素追加到此集合的末尾
public boolean remove(E e)删除指定元素,返回值表示是否删除成功
public E remove(int index)删除指定索引处的元素,返回被删除的元素
public E set(int index,E element)修改指定索引处的元素,返回被修改的元素
public E get(int index)返回指定索引处的元素
public int size()返回集合中的元素的个数

观察这些方法可以看到主要操作是增删改查。

增:add,其中添加的数据需要是对象,既可以自定义的,也可以是Java自带的类;

删:分为两个,分别是直接删除数据和根据索引删除数据;

改:set,根据索引修改为某个值;

查:get,根据索引查询。

crtl+F12和alt+7可快速查看一个类中的所有方法。

ArrayList底层原理

下面介绍一下JDK17中的ArrayList类源码:

底层存储数据的是一个数组elementData,size是存储的数据个数。

    private static final int DEFAULT_CAPACITY = 10;transient Object[] elementData;private int size;

1、首先在使用空参构造函数new一个ArrayList对象时会创建一个长度为0的数组。

    // DEFAULTCAPACITY_EMPTY_ELEMENTDATA表示一个长度为0的数组private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};// 将elementData初始化为长度为0的数组public ArrayList() {this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}

2、然后首次添加一个元素时,来看一下add(e)方法:

    public boolean add(E e) {modCount++;add(e, elementData, size);return true;}

在这个方法中会调用带有三个参数的add方法,s表示存入数组中的元素个数,由于s = 0,所以会调用无参的grow方法进行扩容。 

    private void add(E e, Object[] elementData, int s) {if (s == elementData.length)elementData = grow();elementData[s] = e;size = s + 1;}

下面来看一下grow()方法:

在这个方法中会调用带一个参数的grow方法,并将size+1传过去。

   private Object[] grow() {return grow(size + 1);}

再来看一下 grow(int minCapacity) 方法:

其中minCapacity表示添加所需的最小容量。

在第一次添加时会执行else后面的语句,创建一个长度为DEFAULT_CAPACITY = 10的数组。

当存第11个元素时会进行扩容,调用了newLength方法。

    private Object[] grow(int minCapacity) {int oldCapacity = elementData.length;if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {int newCapacity = ArraysSupport.newLength(oldCapacity,minCapacity - oldCapacity, /* minimum growth */oldCapacity >> 1           /* preferred growth */);return elementData = Arrays.copyOf(elementData, newCapacity);} else {return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];}}

比较minCapacity - oldCapacity和oldCapacity >> 1哪个大? 

当添加一个元素时,minCapacity - oldCapacity = 1,而oldCapacity >> 1 = oldCapacity / 2最小也为5,是肯定大于minCapacity - oldCapacity的,所以扩容后的数组长度为1.5*length。

    public static int newLength(int oldLength, int minGrowth, int prefGrowth) {// preconditions not checked because of inlining// assert oldLength >= 0// assert minGrowth > 0int prefLength = oldLength + Math.max(minGrowth, prefGrowth); // might overflowif (0 < prefLength && prefLength <= SOFT_MAX_ARRAY_LENGTH) {return prefLength;} else {// put code cold in a separate methodreturn hugeLength(oldLength, minGrowth);}}

来看一下addAll方法:

    // addAll方法添加的元素为一个集合public boolean addAll(Collection<? extends E> c) {// 首先将集合c转换为数组aObject[] a = c.toArray();modCount++;// 获取数组a的长度赋给变量numNewint numNew = a.length;if (numNew == 0)return false;Object[] elementData;final int s;//如果numNew大于数组剩下的空间,则将数组需扩容if (numNew > (elementData = this.elementData).length - (s = size))elementData = grow(s + numNew);System.arraycopy(a, 0, elementData, s, numNew);size = s + numNew;return true;}

minCapacity - oldCapacity表示需要增加的数组的长度,oldCapacity / 2表示扩的长度。

如果minCapacity - oldCapacity大于oldCapacity / 2,则证明扩容的长度oldCapacity / 2是不够的,所以此时以minCapacity - oldCapacity为准。 

综上所述底层原理为:

①在创建ArrayList对象时会初始化一个长度为0的数组;

②当首次调用add(e)添加字符串时,会将数组的长度扩容为10;

在后续添加时:

当添加一个元素时且存满时会扩容,扩容之后的数组长度是1.5*length;

如果一次添加很多个元素且超过扩容后的数组长度时则会以实际个数进行扩容。

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

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

相关文章

PVE更新 报错过程解决

Proxmox 报错提示 E: Failed to fetch https://enterprise.proxmox.com/debian/ceph-quincy/dists/bookworm/InRelease 401 Unauthorized E: The repository https://enterprise.proxmox.com/debian/ceph-quincy bookworm InRelease is not signed.Proxmox 报错提示 Tempor…

笔记本重装系统怎么操作? windows电脑重装系统,超实用的四种方法

重新安装操作系统是维护计算机性能和确保系统稳定运行的重要步骤。对于 Windows 笔记本用户而言&#xff0c;熟悉重装系统的方法可以帮助他们解决各种问题&#xff0c;从提高系统速度到修复软件故障。然而具体来讲&#xff0c;笔记本重装系统怎么操作呢&#xff1f;接下来&…

input的23种属性

button 定义可点击的按钮&#xff08;通常与 JavaScript 一起使用来启动脚本&#xff09;。 checkbox 定义复选框。 color 定义拾色器。 date 定义 date 控件&#xff08;包括年、月、日&#xff0c;不包括时间&#xff09;。 datetime 定义 date 和 time 控件&…

AngularJS 参考手册

AngularJS 参考手册 1. 引言 AngularJS,一种由Google维护的开源前端Web框架,自2010年发布以来,已成为Web开发领域的重要工具。它允许开发者使用HTML作为模板语言,并扩展HTML的语法,以清晰简洁地表达应用的组件。本参考手册旨在为开发者提供AngularJS的全面指南,包括其核…

LLDP 基本原理

LLDP 简介 定义 LLDP&#xff08;Link Layer Discovery Protocol&#xff0c;链路层发现协议&#xff09;是 IEEE 802.1ab 中定义的第二层发现&#xff08;Layer 2 Discovery&#xff09;协议。 LLDP 提供了一种标准的链路层发现方式&#xff0c;可以将本端设备的主要能力、…

单片机使用printf在串口输出字符串

把字符串使用printf输出的本质 实际上调用了putchar和串口字符输出函数&#xff0c;参考 以51单片机中的程序为例 在主函数中使用printf函数向串口发送字符串&#xff0c;当然保证已经定义好串口的波特率等参数 while(1){//uart0SendString("start....\n");prin…

服务器巡查脚本

脚本编程步骤 脚本编程一般分为以下几个步骤&#xff1a; 需求分析&#xff1a;根据系统管理的需求&#xff0c;分析脚本要实现的功能、功能实现的层次、实现的命令与语句等&#xff1b; 命令测试&#xff0c;将要用到的命令逐个进行测试&#xff0c;以决定使用的选项要设置…

新书速览|解密AI绘画与修图: Stable Diffusion+Photoshop

《解密AI绘画与修图&#xff1a; Stable DiffusionPhotoshop》 本书内容 《解密AI绘画与修图&#xff1a;Stable DiffusionPhotoshop》全面介绍了Photoshop和Stable Diffusion的交互方式&#xff0c;以及各自的AI功能和具体使用方法。除了讲解功能&#xff0c;还通过实际案例加…

力扣1010.总持续时间可被60整除

力扣1010.总持续时间可被60整除 单次循环遍历 每个数存%60的值 class Solution {public:int numPairsDivisibleBy60(vector<int>& time) {int n time.size();for(int i0;i<n;i)time[i] % 60;int res0;vector<int> cnt(60,0);for(auto t:time){//这么写可…

SpringBoot防抖方案(防止表单重复提交)

SpringBoot防抖方案&#xff08;防止表单重复提交&#xff09; 1.应用场景&#xff08;什么是防抖&#xff09; 所谓防抖&#xff0c;一是防用户手抖&#xff0c;二是防网络抖动。在Web系统中&#xff0c;表单提交是一个非常常见的功能&#xff0c;如果不加控制&#xff0c;容…

深度遍历-牛牛的果实迷宫

目录 一、问题描述 二、解题思路 1.返回格式 2.使用深度遍历 3.注意上下左右的实现方式 三、代码实现 四、刷题链接 一、问题描述 二、解题思路 1.返回格式 这个题目的问题返回格式是Point(x,y)&#xff1b;x代表最短路径距离&#xff0c;y表示最短路径数量 如果没有…

Linux中的库

什么是库&#xff1f; 库是一组预先编译好的方法/函数的集合&#xff0c;其他程序想要使用源文件中的函数时&#xff0c;只需在编译可执行程序时&#xff0c;链接上该源文件生成的库文件即可。 库分为两类&#xff1a;静态库和动态库 在Linux系统中&#xff0c;以.a为后缀的…

Animate软件基础:删除图层或文件夹

Animate软件中&#xff0c;图层或者图层文件夹同样可以进行删除操作&#xff0c;不过需要注意的是&#xff0c;删除图层或者删除文件夹&#xff0c;都会将其中所有的内容删除。 要选择图层或文件夹&#xff0c;可以单击时间轴中该图层或文件夹的名称&#xff0c;或者单击图层中…

003 选择排序(lua)

文章目录 1selectionSort.lua2selectionSort.lua复杂度SortingHelper.lua 先挑最值&#xff0c;再把剩下的挑最值&#xff0c;再把剩下的挑最值。。。 1selectionSort.lua -- 排序函数 function selectionSort(arr) -- 外层循环&#xff0c;从数组的第一个元素开始&#xff…

2-自动驾驶关键技术框架

框架 来自《自动驾驶汽车决策与控制》这本书 三大技术 车载平台的关键技术&#xff1a; 环境感知技术&#xff1a;这是自动驾驶车辆能够“看”和“感知”周围世界的技术。它包括使用摄像头、雷达、激光雷达&#xff08;Lidar&#xff09;和超声波传感器来检测和识别道路、障…

LeetCode21-合并两个有序链表

题目 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4] 示例 2&#xff1a; 输入&#xff1a;l1 [], l2 [] 输出&#xf…

ZYNQ MPSOC烧写问题记录

1、如果带有ARM代码&#xff0c;则ZYNQ MPSOC烧写的烧写是通过ViTIS进行的&#xff0c;通过JTAG模式进行烧写&#xff0c;如下图的PS_MODEx配置成0000&#xff0c;这个只与硬件相关&#xff0c;硬件拉高拉低。 2、如果不带ARM代码&#xff0c;则烧写过程与前版本一致。

发现传统之美,AI赋能非遗传承

大家好&#xff0c;今天想在本片博文分享下关于皮影这项非物质文化遗产&#xff0c;以及如何简单借助人工智能AI赋能皮影的奇妙可能。 皮影戏的魅力 在喧嚣的现代生活中&#xff0c;我们不应该忘记那些传统的手工艺和技艺&#xff0c;它们是中华文化的瑰宝&#xff0c;它们是…

新手做ASO优化必须要了解的8大指标

在进行 ASO 优化时&#xff0c;以下这些指标通常应优先考虑&#xff1a; 1. 关键词排名 - 这是衡量 ASO 效果的关键指标之一。了解您的应用在特定关键词搜索结果中的位置&#xff0c;有助于评估优化策略的有效性。 2. APP下载量 - 直接反映了应用的受欢迎程度和ASO工作对吸…

ONLYOFFICE8.1版本桌面编辑器——功能测评

一、编辑DOCX 相信大家都有写word文档的经历&#xff0c;不知道大家是不是跟我一样&#xff0c;感觉做一个word不难&#xff0c;但想做好一个word却很麻烦&#xff0c;功能太多&#xff0c;看的人眼花缭乱&#xff0c;有时候一个功能要找很久&#xff0c;甚至有的功能用一辈子都…