【Java容器(jdk17)】ArrayList深入源码,就是这么简单
ArrayList深入源码
- 一、ArrayList源码解析
- 1. MIXIN 的混入
- 2. 属性说明
- 3. 构造方法
- 4. 其他方法(核心)
- iterator 和 listIterator 方法
- add方法
- remove 方法
- sort方法
- 其他
- 二、ArrayList 为什么是线程不安全的?体现哪些方面呢?
- 三、ArrayList 细节汇总
前言:
个人觉得看源代码会增进不少知识,一直都是看别人写的博客中的代码片段,没自己静下心来去看过,接下来体验体验源码的快乐。
一、ArrayList源码解析

对 ArrayList 相应关系有了大致的了解后,咱由外到里依次深入。
1. MIXIN 的混入
ArrayList 利用 MIXIN 的思想,实现了多继承。
说明其实现的接口:
Serializable接口:使得ArrayList 支持序列化和反序列化。RandomAccess接口:该接口是一个标记接口,意在标明ArrayList 具备快速随机访问的能力,使用for 会比使用 迭代器(iterator)访问速度要快。LinkedList 那边即不具备这种能力,所以不存在这种标记(原因是因为LinkedList 底层是链表,访问都是从根到尾的,所以它使用迭代器会更快)。Cloneable接口:也是一个标记接口,实现了它便可以去重写Object 下的clone 方法,利于对象进行创建副本。(注意:是ArrayList 实现了Cloneable接口,当利用多态向上转型为List 时,是不可以使用的。)
下面是 ArrayList 内部重写的 clone 方法的代码。
/*** Returns a shallow copy of this {@code ArrayList} instance. (The* elements themselves are not copied.)** @return a clone of this {@code ArrayList} instance*/public Object clone() {try {ArrayList<?> v = (ArrayList<?>) super.clone();v.elementData = Arrays.copyOf(elementData, size);v.modCount = 0;return v;} catch (CloneNotSupportedException e) {// this shouldn't happen, since we are Cloneablethrow new InternalError(e);}}
emmmm…这里我不知道返回值的数据类型不直接为 ArrayList,一般我去重写的话就会直接。。。
2. 属性说明




3. 构造方法
ArrayList 有三个构造方法,俩有参,一无参的。


第三个描述的那个构造方法如何使用呢 ?
由于Arrays.asList() 得到的集合固定大小的,是由Arrays内部类所实例化的,是没有 clone(),add(),remove(),clear()等这样的动态操作的,但如果想要使用这种动态操作怎么办呢?
那咱就可以利用这个构造方法,看代码更清晰:
String[] s = {"xx","yy"};//List<String> xxx = Arrays.asList(s);//xxx.add("mm"); /*这里运行最后是会报异常的,这是因为Arrays 里面有个ArrayList 的内部类,它没有重写add和remove等方法。但没运行是不会爆红的,虽然没有重写那些方法,但该内部类继承了AbstractList,这个类里面这些方法不是抽象的...*/List<String> list = new ArrayList<>(Arrays.asList(s));list.add("mm");list.forEach(System.out::println);// 正常输出

4. 其他方法(核心)
先不说方法,先说说类里面实现的Iterator接口和它的子接口,ListIterator接口。(虽然ArrayList 实例对象用迭代器的话比较少,但是量变质不变,LinkedList 可以用啊)。
iterator 和 listIterator 方法

- 看看Iterator 接口的实现类
Itr内部吧:




- 再来看看
ListIterator接口实现类ListItr(继承了Itr) 的内部吧:


这里继承,所以forEachRemaining方法也是可以使用的。
有了 listIterator() , 不会还有人用 iterator() 吧。注意ListIterator 只在List 集合中出现了哦,也就是 Vector、ArrayList、LinkedList、Stack这样的。
也可以看看 JAVA中ListIterator和Iterator详解与辨析 这篇博客对其的一些解释。
add方法
add 对外提供的方法有俩,
add(E e)和add(int index, E e)。它俩有公共的点是,判断类内定义的elementData数组长度是否和元素size(个数)相匹配,是否需要扩容。
也就是说它们俩有一个共同的方法,让elementData扩容。咋括滴勒,咱来看看这个grow方法内部。

咱看别人博客都说是1.5倍扩容的,但是是怎么个扩容呢?下面看源码分析分析。

通过调用 ArraysSupport类中的newLength方法,我们获得newCapacity后,通过Arrays.copyOf完成扩容。
- 先来看看
ArraysSupport类中的newLength方法。(1.5倍的由来)

- 再来看看
Arrays.copyOf方法调用吧:

它内部用的是System.arraycopy这个方法。这是核心啊,我觉得这也是ArrayList 性能要比较好的关键。这玩意将数据复制给一个副本然后返回给elementData数组。arraycopy 是本地(native)方法。它强在它是浅拷贝,它是直接拷贝所存放的地址,而不是像深拷贝那样重新分配内存。
有关浅拷贝和深拷贝,可以看看这篇《浅拷贝和深拷贝》,或者我写的这篇《clone方法》。
了解完如何扩容之后,再来看看俩方法的具体实现:
- add(E e)

- add(int index,E e)

remove 方法
remove 方法也有两种对外提供,remove(int index),remove(Object obj)。
它们都是根据索引去调用内部的 fastRemove(Object[] es, int i)方法去进行移除。也是调用System下面的arraycopy方法,然后把那个设置为空(null),让GC回收。
咱先来看看 fastRemove 方法的实现吧:

- remove(int index)

- remove(Object obj)

有关 mark 标记的使用可以看这篇博客《mark标号》。
从代码可以看出,不管传入的参数是空还是非空,都会对 elementData 进行操作进行删除。
sort方法
从jdk1.8 后,List接口就引入了sort 这个默认方法。
- List 中的 sort 方法:

- ArrayLIst 重写的 sort 方法(重写的原因很简单,ArrayList内部本就是动态数组所构的,用迭代器去重写对元素进行设置纯属是多余):

及其舒适简单。
可以直接用LIst集合中的sort了,其实调用Collections 工具类中的sort 方法,最后还是会回到List 集合中,还不如直接使用呢。
其他
还有一些常用的 方法,比如:
- set(int index,E element)
- isEmpty()
- get(int index)
- indexOf(Object)
- lastIndexOf(Object)
- clear()
- toArray()
- contains()
trimToSize()还是通过Arrays.copyOf 将数组长度变成和数组元素个数(size)一致,可以减少空间的损失。- …
理解了 ArrayList 的本质,这些方法的实现其实自己想也想的出来。
二、ArrayList 为什么是线程不安全的?体现哪些方面呢?
可以看看这篇博客写的几点线程不安全的情况以及其测试。
《ArrayList为什么线程不安全 线程不安全体现在哪些方面 源码角度分析其具体原因》
三、ArrayList 细节汇总
- ArrayList 是基于动态数组实现的,当进行插入或删除操作的时候,都会进行数组的拷贝复制。
ArrayList它很多地方是分步进行操作的,**而且内部元素也是可以为 null 的。**它不是线程安全的。ArrayList删除元素时,只会改变元素的个数(size),而不会改变容量(elementData.length),如果想要更改,可以调用trimToSize()方法,它会给你改成和元素个数一样的值。
相关文章:
【Java容器(jdk17)】ArrayList深入源码,就是这么简单
ArrayList深入源码一、ArrayList源码解析1. MIXIN 的混入2. 属性说明3. 构造方法4. 其他方法(核心)iterator 和 listIterator 方法add方法remove 方法sort方法其他二、ArrayList 为什么是线程不安全的?体现哪些方面呢?三、ArrayLi…...
【Java 面试合集】简述下Java的三个特性 以及项目中的应用
简述下Java的特征 以及项目中的应用 1. 概述 上述截图中就是Java的三大特性,以及特性的实现方案。接下来就每个点展开来说说 2. 封装 满足:隐藏实现细节,公开使用方法 的都可以理解为是封装 而实现封装的有利手段就是权限修饰符了。可以根据…...
git基本概念图示【学习】
基本概念工作区(Working Directory)就是你在电脑里能看到的目录,比如名字为 gafish.github.com 的文件夹就是一个工作区本地版本库(Local Repository)工作区有一个隐藏目录 .git,这个不算工作区,…...
微前端qiankun架构 (基于vue2实现)使用教程
工具使用版本 node --> 16vue/cli --> 5 创建文件 创建文件夹qiankun-test。 使用vue脚手架创建主应用main和子应用dev 主应用 安装 qiankun: yarn add qiankun 或者 npm i qiankun -S 使用qiankun: 在 utils 内创建 微应用文件夹 microApp,在该文件夹…...
记录robosense RS-LIDAR-16使用过程3
一、wireshark抓包保存pcap文件并解析ubuntu18安装wireshark,参考下面csdn教程,官网教程我看的一脸蒙(可能英语太差)https://blog.csdn.net/weixin_46048542/article/details/121730448?spm1001.2101.3001.6650.2&utm_medium…...
【博学谷学习记录】大数据课程-学习第七周总结
Hadoop配置文件修改 Hadoop安装主要就是配置文件的修改,一般在主节点进行修改,完毕后scp下发给其他各个从节点机器 文件中设置的是Hadoop运行时需要的环境变量。JAVA_HOME是必须设置的,即使我们当前的系统中设置了JAVA_HOME,它也…...
154、【动态规划】leetcode ——494. 目标和:回溯法+动态规划(C++版本)
题目描述 原题链接:494. 目标和 解题思路 (1)回溯法 本题的特点是nums中每个元素只能使用一次,分别试探加上nums[index]和减去nums[index],然后递归的遍历下一个元素index 1。 class Solution { public:int res …...
MySQL-窗口函数
窗口函数概念常用窗口函数聚合窗口函数专用窗口函数语法OVER子句window_specwindow_name (命名窗口)partition_clause 分区order_clause 排序frame_clause 范围 (指定窗口大小)使用限制练习准备概念 窗口函数对一组查询执行类似于聚合的操作。然而&#…...
【C++设计模式】学习笔记(1):面向对象设计原则
目录 简介面向对象设计原则(1)依赖倒置原则(DIP)(2)开放封闭原则(OCP)(3)单一职责原则(SRP)(4)Liskov替换原则(LSP)(5)接口隔离原则(ISP)(6)优先使用对象组合,而不是类继承(7)封装变化点(8)针对接口编程,而不是针对实现编程结语简介 Hello! 非常感谢您阅读海…...
[测开篇]设计测试用例的方法如何正确描述Bug
文章目录为什么测试人员要写测试用例?怎样设计测试用例?(总的方面)1.基于需求设计测试用例(总的方面) 2.页面(总的方面) 3.非功能性测试(具体方面) 4.1 等…...
设计模式学习笔记--单例、建造者、适配器、装饰、外观、组合
以下内容根据以下网址及相关视频整理:Android设计模式之单例模式_谬谬清不给我取名字的博客-CSDN博客_android 单例模式 Android设计模式--单例模式的六种实现和单例模式讲解Volatile与Synchronized相关的并发_龙腾腾的博客-CSDN博客_android 单例 volatile java …...
English Learning - Day5 L1考前复习 2023.2.10 周五
English Learning - Day5 L1考前复习 2023.2.10 周五1 单选题:She has the face _________.2 单选题: The goals ________ he fought all his life no longer seemed important to him.3 单选题:Sales director is a position ______ communi…...
C. Prepend and Append
time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Timur initially had a binary string†† s� (possibly of length 00). He performed the following operation several (possibly zero)…...
javassm超市在线配送管理系统
为了解决用户便捷地在网上购物,本文设计和开发了一个超市管理系统。本系统是基于web架构设计,SSM框架 ,使用Mysql数据库管理,综合采用JSP模式来完成系统的相关功能。主要实现了管理员与用户的注册与登陆,个人中心、用户…...
Scratch少儿编程案例-多模式贪吃蛇(无尽和计时)
专栏分享 点击跳转=>Unity3D特效百例点击跳转=>案例项目实战源码点击跳转=>游戏脚本-辅助自动化点击跳转=>Android控件全解手册点击跳转=>Scratch编程案例👉关于作者...
谷歌蜘蛛池怎么搭建?Google蜘蛛池可以帮助谷歌排名吗?
本文主要分享关于谷歌蜘蛛池的搭建疑问,以及Google对谷歌排名的影响到底有多大。 本文由光算创作,有可能会被剽窃和修改,我们佛系对待这种行为吧。 谷歌蜘蛛池怎么搭建? 答案是:需要一个内链外链体系复杂的站群系统…...
Kubernetes集群-部署Java项目
Kubernetes集群-部署Java项目(SSG) k8s部署项目java流程图 第一步 打包制作镜像 打包 java源码: application.properties #在有pom.xml的路径下执行 mvn clean package制作镜像: 将刚才打包后的文件夹传到,装有dock…...
English Learning - Day54 作业打卡 2023.2.8 周三
English Learning - Day54 作业打卡 2023.2.8 周三引言1. 就算你不喜欢喝酒,也请尝一杯吧。2. 便纵有千种风情,更与何人说?——柳永《雨霖铃》 (来,挑战一下古诗词)3. 虽然忙,我也要参加会议。4. 无论发生什么…...
【Unity题】 1.矩阵旋转,欧拉旋转,四元数旋转各自的优缺点。2.StringBuilder和String的区别
1.矩阵旋转,欧拉旋转,四元数旋转各自的优缺点 矩阵旋转,欧拉旋转,四元数旋转是三种不同的旋转表示方法,下面是它们各自的优缺点: 矩阵旋转: 优点: 1.可以方便地实现复合旋转&…...
【C++面试问答】搞清楚深拷贝与浅拷贝的区别
问题 深拷贝和浅拷贝的区别是面试中的常见问题之一,对于不同的编程语言,这个问题的回答可能稍有差别,下面我们就来探索一下它们之间的异同吧。 先来看看在JavaScript对象的深拷贝与浅拷贝的区别: 浅拷贝:只是复制了…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
