ArrayList源码深度解析
jdk:1.8
一、先看看ArrayList类的整体概述,
ArraList是基于动态数组实现的一种线性列表,这种基于动态数组的好处就是索引比较快,时间复杂度为O(1);但是对数据修改比较慢,因为需要移动数据,移动数据的过程需要消耗大量的时间
因此我们在平时的使用的过程中,需要结合我们的具体业务需求来决定到底应不应该使用ArrayList,如果你只是需要保存数据然后进行查找,这种情况就适合使用ArrayList,如果需要大量的修改,增加或者删除时,这时就不要使用ArrayList
- 先看ArrayList的继承结构,如下图
在Idea中使用Ctrl+H快捷键可以快速查看类的继承结构,不过这是能查看父类(不可以查看父接口)

在idea中也可以查看类的UML图,如下

2.下面两张图是ArrayList类的方法列表,其中绿色的打开的锁表示公共方法,红色的关闭的锁表示私有方法,钥匙形状的图表表示受保护的方法


二、详细介绍
- 主要变量

- 主要方法
- 构造方法

public ArrayList(int initialCapacity)构造方法:该方法带一个整型参数,用该参数可以指定列表的初始容量
public ArrayList()构造方法:
public ArrayList(Collection<? extends E> c)构造方法:用一个一直的集合去初始化一个数组元素
- 主要对方法
public boolean add(E e):向ArrayList中添加一个元素(直接追加到数组的末尾),本质就是向动态数组中添加了一个元素,不过这里并不是简单的直接添加元素,在添加之前需要对数据进行容量检查,确保是否有足够的空间来存放待添加的元素(检查的过程即是调用rangeCheck函数,
当发现空间不足时,会调用ensureCapacityInternal来动态分配空间)
public void add(int index, E element):向数组中指定的位置添加元素,和add(E e)除了添加的位置不同,其他完全一致
public E set(int index, E element)
public E remove(int index)
public boolean remove(Object o)
public void clear()
private void rangeCheck(int index)
private void ensureCapacityInternal(int minCapacity):该函数是数组动态扩容的入口函数,
调用链如下

动态扩容的基本思路:
- 计算出当前数组的大小,以当前的大小的1.5倍(即上图中的newCapacity)作为扩容后的大小
- 判断newCapacity和传入的最小容量需求minCapacity,如果newCapacity<minCapacity,这直接把minCapacity赋值给newCapacity
- 检查赋值后的newCapacity是否超过int的最大值(这里用是否小于0来判断是否溢出,溢出直接抛出异常),否则在int的最大值和MAX_ARRAY_SIZE中取较小的值作为最终的newCapacity
- 调用Arrays.copyOf方法,把原始数据复制到扩容的数组,经过以上步骤后,数组的
private void ensureExplicitCapacity(int minCapacity):和int的最大值以及数据默认的最大容量比较,得出最终的扩容容量
private void grow(int minCapacity):该方法是在确定了扩容后的数组大小后,真正执行扩容的步骤 总结:在对ArrayList进行操作的时候都会去判断是否越界,即执行rangeCheck方法,以及在向ArrayList中插入数据时判断是否需要扩容
ArrayList源码深度解析的更多相关文章
- mybatis 3.x源码深度解析与最佳实践(最完整原创)
mybatis 3.x源码深度解析与最佳实践 1 环境准备 1.1 mybatis介绍以及框架源码的学习目标 1.2 本系列源码解析的方式 1.3 环境搭建 1.4 从Hello World开始 2 ...
- spring源码深度解析— IOC 之 容器的基本实现
概述 上一篇我们搭建完Spring源码阅读环境,spring源码深度解析—Spring的整体架构和环境搭建 这篇我们开始真正的阅读Spring的源码,分析spring的源码之前我们先来简单回顾下spr ...
- spring源码深度解析— IOC 之 默认标签解析(上)
概述 接前两篇文章 spring源码深度解析—Spring的整体架构和环境搭建 和 spring源码深度解析— IOC 之 容器的基本实现 本文主要研究Spring标签的解析,Spring的标签 ...
- spring源码深度解析— IOC 之 默认标签解析(下)
在spring源码深度解析— IOC 之 默认标签解析(上)中我们已经完成了从xml配置文件到BeanDefinition的转换,转换后的实例是GenericBeanDefinition的实例.本文主 ...
- spring5 源码深度解析----- 被面试官给虐懵了,竟然是因为我不懂@Configuration配置类及@Bean的原理
@Configuration注解提供了全新的bean创建方式.最初spring通过xml配置文件初始化bean并完成依赖注入工作.从spring3.0开始,在spring framework模块中提供 ...
- Spring源码深度解析之Spring MVC
Spring源码深度解析之Spring MVC Spring框架提供了构建Web应用程序的全功能MVC模块.通过策略接口,Spring框架是高度可配置的,而且支持多种视图技术,例如JavaServer ...
- Spring源码深度解析之数据库连接JDBC
Spring源码深度解析之数据库连接JDBC JDBC(Java Data Base Connectivity,Java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供 ...
- Spring源码深度解析之事务
Spring源码深度解析之事务 目录 一.JDBC方式下的事务使用示例 (1)创建数据表结构 (2)创建对应数据表的PO (3)创建表和实体之间的映射 (4)创建数据操作接口 (5)创建数据操作接口实 ...
- 源码深度解析SpringMvc请求运行机制(转)
源码深度解析SpringMvc请求运行机制 本文依赖的是springmvc4.0.5.RELEASE,通过源码深度解析了解springMvc的请求运行机制.通过源码我们可以知道从客户端发送一个URL请 ...
随机推荐
- Table上下滚动
<table> <tr> <td> <div id="marquees"> <!-- 这些是字幕的内容,你可以任意定义 --& ...
- ionic3包还原使用yarn命令执行步骤(解决ionic3懒加载报找不到 module的错误)
使用cnpm 还原ionic3.6的依赖包的时候 可以正常还原,但是使用懒加载就会报找不到 module 的错误.最简单的解决办法是删除node_modules 挂个vpn 重新执行npm insta ...
- HDU 2089 不要62【数位DP入门题】
不要62 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- plsql分支,循环,异常
pl/sql 分支,循环和异常分支: DECLARE BEGIN END; 循环:loop,while,for 1.LOOP EXIT WHEN ...
- java汉字获取首字母
前言 在项目中很多时候我们需要获取姓名或者名称的首字母或者全拼,以用于模糊查询或者字母查询,在这里分享一个实例:供小伙伴们参考. 导入jar包 <dependency> <group ...
- 训练continue
11.16 树状数组 http://codeforces.com/contest/1070/problem/C digit sum+% dp http://codeforces.com/contest ...
- poj 1068(模拟题)
Parencodings Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 23545 Accepted: 13802 De ...
- wannafly挑战赛14
第一次打wannafly..觉得自己好菜啊... 题目描述 在三维空间中,平面 x = 0, y = 0, z = 0,以及平面 x + y + z = K 围成了一个三棱锥. 整天与整数打交道的小明 ...
- [CODECHEF]LCM
题意:询问满足$1\leq x\leq n,1\leq y\leq m$且$x,y$均无平方因子的有序对$(x,y)$的$[x,y]$之和,多组数据 以下假设$n\leq m$,设$S(n)=\fra ...
- 二叉搜索树BStree
二叉搜索树,实际上是有点类似于二分查找.实际上很简单,就是递归.直接上代码,有点要注意的就是删除的时候,如果是左子树和右子树都存在的话,要寻找继承者(successor). import java.u ...