详解ArrayList

news2024/10/1 6:34:07

目录

1.数据结构

2.初始化

2.1.默认构造

2.2.带参构造

3.扩容

 3.1.判断需要多少容量

 3.2.判断是否需要扩容

 3.3.扩容

4.遍历

5.拷贝

6.序列化


JDK版本:JDK8

1.数据结构

底层使用Object类型的数组实现,线程不安全,添加元素时如果内存已满则会开辟新空间,将原数组copy过去。

transient Object[] elementData;

public boolean add(E var1) {
        this.ensureCapacityInternal(this.size + 1);
        this.elementData[this.size++] = var1;
        return true;
    }

2.初始化

2.1.默认构造

默认构造是将elementData的引用指向一个final类型的Object[],这个final类型的Object[]在声明时指向的是一个空数组,因此采用默认构造实例化出来的ArrayList对象底层的elementData是没有容量的,因此第一次add就需要扩容。

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = new Object[0];
public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

这样设计的目的是节约内存,采用默认构造实例化的对象,在没有用到的时,所有数组都指向一块内存,只有用到时才从新分配。

2.2.带参构造

 带参构造才会实例化出一个指定大小的elementData。

3.扩容

每次add时都会调用ensureCapacityInternal方法判断当前数组容量够不够,不够则扩容。

ensureCapacityInternal里需要干两件事:

  1. 判断需要多少容量,即calculateCapacity方法。
  2. 判断是否需要扩容,即ensureExplicitCapacity方法。

 3.1.判断需要多少容量

这一步主要是判断如果是调用默认构造实例化的数组,需要扩容的大小是多少。

如果是采用默认构造实例化出的ArrayList对象,

elementData指向的是DEFAULTCAPACITY_EMPTY_ELEMENTDATA,空间大小为0,

如果需要的空间数量不超过DEFAULT_CAPACITY(即10个),则扩容出10个空间即可。

如果需要的空间数量超过DEFAULT_CAPACITY(10个),则扩容出实际需要的空间数量。

 3.2.判断是否需要扩容

判断需要的容量是否超过当前数组的容量如果超过则扩容

 3.3.扩容

新建一个新数组,长度为老数组的1.5倍(老数组长度+老数组长度右移1位(老数组长度/2^1)),然后将老数组中的元素copy到新数组中。

4.遍历

ArrayList的遍历器(iterator)以内部类的方式实现,实现Iterator接口

三个成员变量:

cursor:游标,用于遍历

lastRet:

expectedModCount:操作数,用来确认数据是否还有一致性

 

fail-fast:

为了保证遍历时数据的一致性,ArrayList的iterator有一个fail-fast机制,

即使用iterator遍历期间,只允许通过iterator来对该对象中的数据进行操作。

 而不允许在使用iterator遍历期间,通过其他手段修改对象中的数据。

5.拷贝

 ArrayList实现了Cloneable接口,默认实现浅拷贝,即栈上内容分裂,堆上内容公用。想实现深拷贝,需要手动对成员变量进行一次clone。

6.序列化

ArrayList实现了Serializable接口,

并且重写了writeObject()、readObject(),

elementData[]空间很可能没有全部用完,没用到的位置为空,为了避免浪费内存,所以拷贝时只需要将elementData中的非空元素序列化走。

重写的序列化读写方法主要是为了实现上面的想法。

elementData[]被transient修饰,不会被序列化。

 size记录了前面多少位存有元素,遍历、序列化至size位置即可。

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

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

相关文章

【遇见青山】基于Redis的Feed流实现案例

【遇见青山】基于Redis的Feed流实现案例1.关注推送2.具体代码实现1.关注推送 关注推送也叫做Feed流,直译为投喂。为用户持续的提供"沉浸式”的体验,通过无限下拉刷新获取新的信息。 Feed流产品有两种常见模式: 这里我们实现基本的TimeL…

Python 爬虫工程师面试经验分享,金三银四

🙃 作为一个 Python 爬虫工程师,我可以分享一些我在面试中的经验和建议。 首先一点是在面试中要表现自信、友好、乐于合作,同时对公司的业务和文化也要有一定的了解和兴趣,这些也是公司在招聘中看重的因素。 文章目录&#x1f55b…

第06章_MySQL多表查询

第06章_多表查询 讲师:尚硅谷-宋红康(江湖人称:康师傅) 官网:http://www.atguigu.com 多表查询,也称为关联查询,指两个或更多个表一起完成查询操作。 前提条件:这些一起查询的表之…

node.js基于Vue的英语在线学习网站 vscode+mysql

该系统的基本功能包括管理员、学生、教师三个角色功能模块。 对于管理员可以使用的功能模块主要有首页、个人中心,学生管理、教师管理、班级管理、课程管理,在线学习管理、作业管理、试卷管理、试题管理、 在线论坛、系统管理、考试管理等功能。 对于学生…

STM32F765ZIT6中文规格STM32F765ZGT6引脚图 微控制器MCU

说明STM32F7 32 位 MCUFPU 基于高性能的 ARMCortex-M7 32 位 RISC 内核,工作频率高达 216MHz。Cortex-M7 内核具有单浮点单元(SFPU)精度,支持所有 ARM 单精度数据处理指令与数据类型。同时执行全套 DSP 指令和存储保护单元(MPU)&a…

各CCF期刊点评网站/学术论坛的信息汇总及个人评价

CCF中文期刊投稿选择之篇章一:各CCF期刊点评网站/学术论坛的信息汇总及个人评价中文科技期刊A类(EI检索)中文期刊投稿点评网站整理1.小木虫学术论坛2. Letpub3. Justscience4. 发表记5. 会伴(Conference Partner)6. ijouranl7. 掌桥科研这是以…

Win11的两个实用技巧系列之如何关闭登录密码?

Win11如何关闭登录密码?Win11关闭登录密码的两种解决方法win11是电脑更新后的全新系统,每次开启需要输入密码。有的用户嫌麻烦想要关闭,下面小编就为大家带来了关闭的方法,一起来看看吧有不少用户在升级或者第一次使用Win11系统的时候&#…

uni-app做微信小程序的分包处理

我们的都知道微信小程序有随即随用,用完即走的优点,并且它开发门槛低,但是它也有一个致命的缺点,就是代码包体积的限制,这一缺点让小程序的开发有了一定的限制,现在有一方法可以减少代码包的体积&#xff0…

界面组件Telerik ThemeBuilder R1 2023开创应用主题研发新方式!

Telerik DevCraft包含一个完整的产品栈来构建您下一个Web、移动和桌面应用程序。它使用HTML和每个.NET平台的UI库,加快开发速度。Telerik DevCraft提供最完整的工具箱,用于构建现代和面向未来的业务应用程序,目前提供UI for ASP.NET包含一个完…

汉诺塔递归算法精讲

文章目录前言一、汉诺塔是个啥?二、手动解法三、解法抽象四、递归解法五、总结前言 递归算法是计算机算法中的基础算法,也是非常重要的算法,从某种程度上讲,它有一点儿AI的影子。人脑是可以完成递归思路的,但是对不起…

《爆肝整理》保姆级系列教程python接口自动化(十五)--参数关联接口(详解)

简介 我们用自动化新建任务之后,要想接着对这个新建任务操作,那就需要用参数关联了,新建任务之后会有一个任务的Jenkins-Crumb,获取到这个Jenkins-Crumb,就可以通过传这个任务Jenkins-Crumb继续操作这个新建的任务。 …

自适应布局之淘宝无限适配+rem+微信rpx自适应

一、自适应布局 所谓前端适配,就是为了让移动设计稿在大部分的移动设备上看起来有一致的展示效果,目前比较流行的方法有两种。一种是强制meta viewport宽度为设计稿宽度,一种是使用rem自适应布局的flexible.js。 二、当前流行的移动端自适应…

【刷题笔记】--盛最多水的容器--双指针

题目: 给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明:你不…

Python 高级编程之正则表达式(八)

文章目录一、概述二、正则表达式语法1)字符匹配2)字符集合3)定位符4)分组1、定义分组2、引用分组3、命名分组三、Python 的 re 模块1)re.match() 方法2)re.search() 方法3)re.match() 与 re.sea…

2023最牛教程,手把手教你成为年薪30W的测试开发

随着互联网行业的高速发展,快速高质量的产品版本迭代成为企业始终立于不败之地的迫切需求,而在短期迭代的快节奏中,传统测试工作面对更大压力,无法持续提供高效率高质量的人力支撑,所以越来越多的企业需要技术更为全面…

Leetcode-每日一题1250. 检查「好数组」(裴蜀定理)

题目链接:https://leetcode.cn/problems/check-if-it-is-a-good-array/description/ 思路 方法:数论 题目意思很简单,让你在数组 nums中选取一些子集,可以不连续,子集中的每个数再乘以任意的数的和是否为1&#xff…

netty

Netty的介绍Netty是异步的(指定回调处理)、基于事件驱动的网络应用框架,用于快速开发高性能、高可靠性的网络IO程序。Netty本质是一个NIO框架,适用于服务器通讯相关的多种应用场景,分布式节点远程调用中Netty往往作为R…

RTT 消息邮箱

1.邮箱概念 邮箱服务是实时操作系统中一种典型的线程间通信方法。举一个简单的例子,有两个线程,线程 1 检测按键状态并发送,线程 2 读取按键状态并根据按键的状态相应地改变 LED 的亮灭。这里就可以使用邮箱的方式进行通信,线程 …

SpringCloud保姆级搭建教程五---Redis

首先,这个和微服务没有直接的关系,只是在代码开发当中要使用的一个工具而已,为了提高这个系统的性能,加快查询效率等方面而使用它1、首先,要先安装redis到电脑上,这里依然是在windows上演示,之后…

window11, WSL, Ubuntu 20.04 编译TensorRT源码并且安装 TensorRT

一、安装参考 1.ubuntu18.04TensorRT 配置攻略 ubuntu18.04TensorRT 配置攻略 - 简书卷积网络的量化和部署是重要环节,以前我们训练好模型后直接trace进行调用,参考(C windows调用ubuntu训练的PyTorch模型(.pt/.pth)…