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

一文了解 ArrayList 的扩容机制

了解 ArrayList

在 Java 中常用集合类之间的关系如下图所示:

在这里插入图片描述

从图中可以看出 ArrayList 是实现了 List 接口,并是一个可扩容数组(动态数组),它的内部是基于数组实现的。它的源码定义如下:

public class ArrayList<E> extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, java.io.Serializable{
}
  • ArrayList 可以实现所有可选择的列表操作,允许所有的元素,包括空值。ArrayList 还提供了内部存储 List 的方法,它能够完全替代Vector,只有一点例外,ArrayList 不是线程安全的容器。

  • ArrayList 有一个容量的概念,这个数组的容量(size)就是 List 用来存储元素的容量。

  • ArrayList 不是线程安全的容器,如果多个线程中至少有两个线程修改了 ArrayList 的结构的话就会导致线程安全问题,作为替代条件可以使用线程安全的 List,应使用 Collections.synchronizedList

    List list = Collections.synchronizedList(new ArrayList<>());
    
  • ArrayList 具有 fail-fast 快速失败机制,能够对 ArrayList 作出失败检测。当在迭代集合的过程中该集合在结构上发生改变的时候,就有可能会发生 fail-fast,即抛出ConcurrentModificationException异常。

通过源码分析 ArrayList 的扩容机制

当使用空参构造器进行创建 ArrayList 的时候,实际上给 elementData 初始化赋值的是一个空数组 {}

//数组列表的大小(包含的元素数),初始化为 0
private int size;
//存储数组列表元素的数组缓冲区。
transient Object[] elementData;
//默认初始化容量为10
private static final int DEFAULT_CAPACITY = 10;
//默认空数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//使用空参构造器创建 ArrayList 时,实际上初始化赋值的是一个空数组
public ArrayList() {this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

当首次调用 add(E e) 方法进行添加第一个元素时,会首先调用 ensureCapacityInternal 方法,传入参数 1

//将指定的元素追加到此列表的末尾
public boolean add(E e) {ensureCapacityInternal(size + 1);  // Increments modCount!!elementData[size++] = e;return true;
}

ensureCapacityInternal 方法中,会调用 calculateCapacity 方法,传入参数为 elementData,1

private void ensureCapacityInternal(int minCapacity) {ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}

calculateCapacity 方法中,判断 elementData 是否为空数组,由于是初始化赋值的是一个空数组 {},所以符合 if 条件,返回 (DEFAULT_CAPACITY, minCapacity)【10,1】 中大的那个,此时返回 10

private static int calculateCapacity(Object[] elementData, int minCapacity) {if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {return Math.max(DEFAULT_CAPACITY, minCapacity);}return minCapacity;
}

接着返回到 ensureCapacityInternal 方法中,继续调用 ensureExplicitCapacity 方法验证是否需要扩容,传入参数 10 ,此时 minCapacity=10,elementData.length=0 ,相减小于0,执行 grow 方法扩容,传入参数 10,当添加第2-10个元素时,不会执行 grow 方法,一直到数组已经满元素时才执行 grow 方法扩容:

private void ensureExplicitCapacity(int minCapacity) {modCount++;// overflow-conscious codeif (minCapacity - elementData.length > 0)grow(minCapacity);
}

grow 方法中,此时 minCapacity=10,oldCapacity=0,newCapacity=0 ,符合 newCapacity - minCapacity < 0 条件,执行 newCapacity = minCapacity; 不满足 newCapacity - MAX_ARRAY_SIZE > 0 ,执行 Arrays.copyOf() 方法将 elementData 指向的数组中的元素复制到新的数组中,新的数组长度为 10,并让 elementData 指向新的数组,int newCapacity = oldCapacity + (oldCapacity >> 1) 完成1.5倍扩容。

private void grow(int minCapacity) {// overflow-conscious codeint oldCapacity = elementData.length;int newCapacity = oldCapacity + (oldCapacity >> 1);if (newCapacity - minCapacity < 0)newCapacity = minCapacity;if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);// minCapacity is usually close to size, so this is a win:elementData = Arrays.copyOf(elementData, newCapacity);
}

相关文章:

一文了解 ArrayList 的扩容机制

了解 ArrayList 在 Java 中常用集合类之间的关系如下图所示&#xff1a; 从图中可以看出 ArrayList 是实现了 List 接口&#xff0c;并是一个可扩容数组&#xff08;动态数组&#xff09;&#xff0c;它的内部是基于数组实现的。它的源码定义如下&#xff1a; public class A…...

牛态已成选股源码

{牛态已成} {条件选股} {其他类型} N:7; A1:(REF(H,N) HHV(H,((2 * N) 1))); B1:FILTER(A1,N); C1:BACKSET(B1,(N 1)); D1:FILTER(C1,N); A2:(REF(L,N) LLV(L,((2 * N) 1))); B2:FILTER(A2,N); C2:BACKSET(B2,(N 1)); D2:FILTER(C2,N); E1:((REF(LLV(L,(2 * N)),1) REF(…...

Python基础

Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。Python 的设计具有很强的可读性&#xff0c;相比其他语言经常使用英文关键字&#xff0c;其他语言的一些标点符号&#xff0c;它具有比其他语言更有特色语法结构。小编也整理了一套关于学习Python入门…...

浅显易懂的说清楚小游戏与H5游戏的技术区别

从“跳一跳”到“羊了个羊”微信小游戏上线4年时间&#xff0c;除了涌现出不少火爆全网的小游戏之外&#xff0c;也有类似于“动物餐厅”、“口袋奇兵”等游戏得以在此孵化繁荣&#xff0c;凭借着微信强大的社交属性小游戏成为游戏厂商在桌面端、App 端、H5 端之外争夺的另一个…...

【Python入门第七天】Python 数字

Python 数字 Python 中有三种数字类型&#xff1a; intfloatcomplex 为变量赋值时&#xff0c;将创建数值类型的变量&#xff1a; 实例 x 10 # int y 6.3 # float z 2j # complex如需验证 Python 中任何对象的类型&#xff0c;请使用 type() 函数&#xff1a; 实…...

Python自动化测试 软件测试最全教程(附笔记),看完可就业

最近看到很多粉丝在后台私信我&#xff0c;叫我做一期Python自动化测试的教程&#xff0c;其实关于这个问题&#xff0c;我也早就在着手准备了&#xff0c;我录制了一整套完整的Python自动化测试的教程&#xff0c;都上传在B站上面&#xff0c;大家有兴趣的可以去看一下&#x…...

Windows 安装Tomcat

版本:tomcat8.5jdk-8u231一.解压JDK安装包 更换JDK安装路径二.解压安装Tomcat 选择jdk安装路径更换tomcat安装路径三.设置环境变量 1.“环境变量”界面中系统变量点击”新建“&#xff0c;创建CATALINA_HOMEC:\RESSET\tomcat&#xff08;Tomcat服务器的根目录&#xff09;2.创建…...

知识图谱业务落地技术推荐之图数据库汇总

0.图数据库排名 链接:https://db-engines.com/en/ranking/graph+dbms 0.1简要分析(各种图数据库属性) Neo4j(主流) 历史悠久且...

2023新华为OD机试题 - 最小传递延迟(JavaScript) | 刷完必过

最小传递延迟 题目 通讯网络中有N个网络节点 用1 ~ N进行标识 网络通过一个有向无环图进行表示 其中图的边的值,表示节点之间的消息传递延迟 现给定相连节点之间的延时列表times[i]={u,v,w} 其中u表示源节点,v表示目的节点,w表示u和v之间的消息传递延时 请计算给定源节点到…...

SpringMVC基础入门(一)之理论基础概念

文章目录SpringMVC1.概念2.常用注解请求与响应1.请求参数2.JSON传输3.常用注解响应1.响应页面2.响应JSON数据Rest风格1.介绍2.常用注解SpringMVC 1.概念 &#xff08;1&#xff09;定义 SpringMVC是一种基于Java实现MVC模型的轻量级Web框架。 &#xff08;2&#xff09;为什…...

前端知识点

一. slice和splice区别&#xff1a; 1.splice改变原数组&#xff0c;slice不改变原数组。 2.splice除了可以删除之外&#xff0c;还可以插入。 3.splice可传入3个参数&#xff0c;slice接受2个参数。slice(start,end)&#xff1a;方法可从已有数组中返回选定的元素&#xff0c…...

【docker知识】从容器中如何访问到宿主机

一、说明 使用 Docker 能实现服务的容器化&#xff0c;并使用容器间网络在它们之间进行通信。有时您可能需要一个容器来与宿主机上非容器化的服务通信。以下是如何从 Docker 容器中访问本地主机或 127.0.0.1的具体方法。 二、方法1&#xff1a;简单的选择 适用于 Windows 和 Ma…...

MySQL入门篇-MySQL常用流程控制函数小结

备注:测试数据库版本为MySQL 8.0 这个blog我们来聊聊常见的流程控制函数 如需要scott用户下建表及录入数据语句&#xff0c;可参考:scott建表及录入数据sql脚本 流程控制函数 函数名函数用途CASEcase语句用于条件判断if()if/else条件判断ifnull()null数据处理nullif()retur…...

大数据技术架构(组件)35——Spark:Spark Streaming(1)

2.3、Spark Streaming2.3.0、OverviewSpark Streaming 是核心 Spark API 的扩展&#xff0c;它支持实时数据流的可扩展、高吞吐量、容错流处理。数据可以从许多来源&#xff08;如 Kafka、Kinesis 或 TCP 套接字&#xff09;获取&#xff0c;并且可以使用复杂的算法进行处理&am…...

实现超大文件上传逻辑

引言 文件上传功能是我们开发中经常会遇到的功能点,当日常开发中遇到小文件&#xff08;比如&#xff1a;头像&#xff09;&#xff0c;可以直接将文件转为字节流直接上传到服务器上即可。但是当遇到大文件这种&#xff08;比如&#xff1a;一部电影至少1个G&#xff09;该怎么…...

JavaScript HTML DOM EventListener

JavaScript HTML DOM EventListener 是一个非常重要的概念&#xff0c;在前端开发中被广泛使用。它是用来监听 HTML DOM 上的事件&#xff0c;并执行特定的代码块。 EventListener 的语法非常简单&#xff0c;下面是一个示例代码&#xff1a; element.addEventListener("…...

构建RFID系统的重要组成部分

RFID读写设备&#xff0c;通常被用来扫描读取安装了RFID电子标签的目标物品&#xff0c;能实现快速批量无接触读写&#xff0c;是构建RFID系统的重要组成部分。RFID读写设备&#xff0c;通常有固定式读写设备和可移动读写设备两种。下面来了解一下RFID的特点&#xff0c;RFID系…...

PID控制算法简介

目录 1 简介 2 比例Proportional 3 积分Integral 4 微分Differential 5 公式 6 积分限幅 7 积分限行 8 相关代码 1 简介 PID控制中有P、I、D三个参数&#xff0c;PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&#…...

【王道数据结构】第八章 | 排序

目录 8.1. 排序的基本概念 8.2. 插入排序 8.2.1. 直接插入排序 8.2.2. 折半插入排序 8.2.3. 希尔排序 8.3. 交换排序 8.3.1. 冒泡排序 8.3.2. 快速排序 8.4. 选择排序 8.4.1. 简单选择排序 8.4.2. 堆排序 8.5. 归并排序和基数排序 8.5.2. 基数排序 8.1. 排序的基本概念 排…...

95后外贸SOHO,年入7位数,他究竟是怎么做的?

外贸SOHO&#xff0c;一年到底能挣多少钱&#xff1f;有人说&#xff1a;“勤勤恳恳&#xff0c;年薪也就十来万吧”&#xff1b;也有人说&#xff1a;“100万而已我早就已经挣到了”&#xff1b;还有人说&#xff1a;“谁说新手难出头&#xff1f;我做跨境半年赚200万&#xf…...

2023年全国最新消防设施操作员精选真题及答案

百分百题库提供消防设施操作员考试试题、消防设施操作员考试预测题、消防设施操作员考试真题、消防设施操作员证考试题库等,提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 一、多选题 15、以下符合电气火灾监控系统监控设备的安装要求的有:( ) A、…...

mysql 无需修改配置文件,即可改变表数据存储位置

由于Linux系统的mysql 默认数据存储在/var/lib/mysql路径下&#xff0c;而该路径装系统时默认大小仅50G&#xff0c;当我们的数据稍微大一点时就会把该空间占满&#xff0c;无法再插入数据。 针对该问题有两种解决办法&#xff1a; 1、修改/etc/my.cnf配置文件&#xff0c;重启…...

轻松解决Session-Cookie 鉴权(含坑)附代码

Session-Cookie 鉴权 cookie介绍 Cookie 存储在客户端&#xff0c;可随意篡改&#xff0c;不安全有大小限制&#xff0c;最大为 4kb有数量限制&#xff0c;一般一个浏览器对于一个网站只能存不超过 20 个 Cookie&#xff0c;浏览器一般只允许存放 300个 CookieCookie 是不可跨…...

pyinstaller使用详细

目录常用命令spec文件配置报错常用命令 pyinstaller -D xxx.py //打包生成目录&#xff08;director&#xff09;pyinstaller -F xxx.py//打包生成单个exe文件pyinstaller xxx.spec //根据现有的spec文件进行打包运行以上命令之一后会生成build、dist文件夹以及xxx.spec文件&a…...

java -数据结构,List相关基础知识,ArrayList的基本使用,泛型的简单、包装类介绍

一、 预备知识-泛型(Generic) 1.1、泛型的引入 比如&#xff1a;我们实现一个简单的顺序表 class MyArrayList{public int[] elem;public int usedSize;public MyArrayList(){this.elem new int[10];}public void add(int key){this.elem[usedSize] key;usedSize;}public …...

RabbitMQ学习总结(10)—— RabbitMQ如何保证消息的可靠性

一、丢失场景 RabbitMQ丢失的以下3种情况: (1)生产者:生产者发送消息至MQ的数据丢失...

购物车案例【版本为vue3】

前言&#xff1a; 首先我们要明白整个购物车的组成。它是由一个主页面加两个组件组合成的。本章主要运用父子之间的通讯&#xff1a; 父传子 子传父 首先新建一个vue3项目&#xff0c;这里有俩种创建方式&#xff1a; vue-cli &#xff1a; ● 输入安装指令 npm init vuelates…...

Multisim14 安装包及安装教程

Multisim14 安装教程 Multisim14下载地址&#xff1a;Kevin的学习站–安装包下载地址 Multisim14 简介&#xff1a; Multisim 14 是美国国家仪器有限公司&#xff08;National Instrument&#xff0c;NI&#xff09;推出的以 Windows 为基础、符合工业标准的、具有 SPICE 最佳仿…...

Java实现简单的图书管理系统源码+论文

简单图书管理系统设计&#xff08;文末附带源码论文&#xff09; 为图书管理人员编写一个图书管理系统&#xff0c;图书管理系统的设计主要是实现对图书的管理和相关操作&#xff0c;包括3个表&#xff1a; 图书信息表——存储图书的基本信息&#xff0c;包括书号、书名、作者…...

前端调试2

一、用chrome调试(node.js)例&#xff1a;const fs require(fs/promises);(async function() {const fileContent await fs.readFile(./package.json, {encoding: utf-8});await fs.writeFile(./package2.json, fileContent); })();1.先 node index.js 跑一下&#xff1a;2.然…...

订阅号怎么做微网站/网站seo专员招聘

联想一下&#xff0c;我们不可能只传输一类数据。通常&#xff0c;我们会一边上网&#xff0c;一遍聊QQ&#xff0c;一边听音乐。这么多数据怎么管理&#xff1f;这就要求我们要用到第4层的协议。 第4层协议就是用来区分不同程序&#xff0c;不同服务的网络通信。在TCP/IP中&am…...

wordpress购买服务器/如何在百度推广网站

1 什么是回调函数&#xff1f; 首先什么是“回调”呢&#xff1f;我的理解是&#xff1a;把一段可执行的代码像参数传递那样传给其他代码&#xff0c;而这段代码会在某个时刻被调用执行&#xff0c;这就叫做回调。如果代码立即被执行就称为同步回调&#xff0c;如果过后再执行&…...

自己怎么做网站卖东西/有免费做网站的吗

文章目录前言1.主从模式2.哨兵模式2.1 哨兵模式的作用2.2 哨兵实现原理2.3 主观下线和客观下线2.4 哨兵模式优缺点3.常见的Redis集群方案3.1 客户端分片客户端分片的优缺点&#xff1a;一致性哈希算法:实现方式&#xff1a;3.2 代理分片3.3 Codis3.4 Redis Cluster前言 在服务…...

单页面网站可以做自适应网站吗/网络营销的方法有哪些?

一、准备 hive下载地址&#xff1a;mirror.bit.edu.cn/apache/hive… 二、Hadoop环境搭建 Hadoop安装和配置&#xff0c;请看Hadoop单机版安装 三、mysql安装 因为Hive的默认元数据是Mysql&#xff0c;所以先要安装Mysql。 首先查看mysql 是否已经安装 rpm -qa | grep mysql 复…...

高新区建网站外包/游戏广告推广平台

正题 Portal 很容易想到如果最小k-1条边之和>最大那条边&#xff0c;那么就可以构成一个k边形。 否则显然构不成一个多边形。 那么很容易可以想到Dp&#xff1a;表示用j条边构成总长度为i的组合有多少种&#xff0c;转移显然&#xff0c;时间复杂度就是&#xff0c;可以获得…...

wordpress国旗/软文技巧

Python作为一门较为灵活的解释型脚本语言&#xff0c;其中定义的main()函数只有当该Python脚本直接作为执行程序时才会执行&#xff1b;当该python脚本被作为模块(module)引入(import)时&#xff0c;其中的main()函数将不会被执行。这是由于两方面原因&#xff0c;一方面&#…...