ArrayList扩容代码分析
ArrayList扩容机制是在面试中频繁出现的问题,平时了解的比较含糊,特此记录!
注意:每次发生扩容,其容量扩充为原来的1.5倍左右
add方法
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
// 是否为刚初始化后的空数组
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {
// modCount为此列表被结构修改的次数。
// 结构修改是指改变列表的大小,或者以某种方式扰乱列表,从而导致正在进行的迭代可能产生不正确的结果。
// 该字段由迭代器和listIterator方法返回的迭代器和列表迭代器实现使用。如果该字段的值意外更改,迭代器(或列表迭代器)将抛出ConcurrentModificationException异常,以响应next、remove、previous、set或add操作。
// 这提供了fail-fast行为(一种错误检测机制,一旦检测到可能发生错误,就立马抛出异常,程序不继续往下执行),而不是在迭代期间面对并发修改时的非确定性行为。
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
扩容方法
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
// 这里使用的是右移计算,比整除高效(注:对于偶数是除2,对于奇数是除2向下取整,所以不完全是1.5倍)
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中的数据复制出newCapacity个,没有的用null填充
elementData = Arrays.copyOf(elementData, newCapacity);
}
主要常量及成员变量
// 默认容量
private static final int DEFAULT_CAPACITY = 10;
// 用于空实例的空数组。
private static final Object[] EMPTY_ELEMENTDATA = {};
// 默认大小的空实例。我们将它与EMPTY_ELEMENTDATA区分开来,以了解添加第一个元素时要膨胀多少。
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
// 集合中的元素存储在其中。当ArrayList中的elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA,并且在其添加第一个元素时,容量将被扩展为DEFAULT_CAPACITY。
transient Object[] elementData;
无参构造
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
ArrayList扩容代码分析的更多相关文章
- ArrayList扩容原理分析
1:代码解读和分析 1.1:构造方法分析 1: public ArrayList(int initialCapacity) { ) { this.elementData = new Object[in ...
- Java ArrayList源码分析(含扩容机制等重点问题分析)
写在最前面 这个项目是从20年末就立好的 flag,经过几年的学习,回过头再去看很多知识点又有新的理解.所以趁着找实习的准备,结合以前的学习储备,创建一个主要针对应届生和初学者的 Java 开源知识项 ...
- ArrayList代码分析
集合算是java中最常用的部分了,阅读该部分jdk代码可以让我们更加清楚的了解其实现原理,在使用时也能心中有数,有利于写出高质量的代码. ArrayList 底层数组实现,初始长度10,超过长度后的自 ...
- java ArrayList的序列化分析
一.绪论 所谓的JAVA序列化与反序列化,序列化就是将JAVA 对象以一种的形式保持,比如存放到硬盘,或是用于传输.反序列化是序列化的一个逆过程. JAVA规定被序列化的对象必须实现java.io.S ...
- Java集合干货——ArrayList源码分析
ArrayList源码分析 前言 在之前的文章中我们提到过ArrayList,ArrayList可以说是每一个学java的人使用最多最熟练的集合了,但是知其然不知其所以然.关于ArrayList的具体 ...
- ArrayList 源码分析
ArrayList 源码分析 1. 结构 首先我们需要对 ArrayList 有一个大致的了解就从结构来看看吧. 1. 继承 该类继承自 AbstractList 这个比较好说 2. 实现 这 ...
- ArrayList源码分析超详细
ArrayList源码分析超详解 想要分析下源码是件好事,但是如何去进行分析呢?以我的例子来说,我进行源码分析的过程如下几步: 找到类:利用 IDEA 找到所需要分析的类(ztrl+N查找ArraLi ...
- 集合源码分析[3]-ArrayList 源码分析
历史文章: Collection 源码分析 AbstractList 源码分析 介绍 ArrayList是一个数组队列,相当于动态数组,与Java的数组对比,他的容量可以动态改变. 继承关系 Arra ...
- ArrayList源码分析超详细(转载)
ArrayList源码分析超详细 ArrayList源码分析超详解 想要分析下源码是件好事,但是如何去进行分析呢?以我的例子来说,我进行源码分析的过程如下几步: 找到类:利用 IDEA 找到所需要 ...
- ArrayList源码分析--jdk1.8
ArrayList概述 1. ArrayList是可以动态扩容和动态删除冗余容量的索引序列,基于数组实现的集合. 2. ArrayList支持随机访问.克隆.序列化,元素有序且可以重复. 3. ...
随机推荐
- 【OpenGL ES】EGL+FBO离屏渲染
1 前言 FBO离屏渲染 中使用 GLSurfaceView 来驱动 Renderer 渲染图片,为了隐藏 GLSurfaceView,将其设置为透明的,并且宽高都设置为1.本文将使用 EGL 代 ...
- 【OpenGL ES】绘制圆形
1 前言 [OpenGL ES]绘制三角形 中介绍了绘制三角形的方法,[OpenGL ES]绘制正方形中介绍了绘制正方形的方法,本文将介绍绘制圆形的方法. OpenGL 以点.线段.三角形为图 ...
- Springboot中如何使用日志框架logback和log4j2?
说明 在这个简短的教程中,我们将探索 Spring Boot 中可用的主要日志记录选项:logback和log4j2 初始设置 使用 starters 时,默认使用 Logback 进行日志记录. 让 ...
- vue项目设置favicon
1.准备一个favicon.ico 放在项目的static文件夹下: 2.修改打包配置 开发环境 修改build/webpack.dev.conf.js,找到new HtmlWebpackPlugin ...
- Java I/O 教程(七) DataOutputStream和DataInputStream
Java DataOutputStream Class Java DataOutputStream class 可以以机器无关方式往指定输出流写入Java原始数据类型,例如int, double, l ...
- SpringBoot学习-图文并茂写Hello World
一. 生成SpringBoot新项目demo 在 https://start.spring.io/ 生成一个新的项目 1. 步骤: 1)Project 选择 Maven Project 2)Sprin ...
- go值接收者和指针接收者的区别
方法的接收者 package main import ( "fmt" ) type Person struct { Name string Age int } func (p Pe ...
- Q查询的高级用法
示例:如前端需要通过下拉框选择需要通过什么过滤字段来查询输入的关键字,后端如何使用Q查询过滤包含输入的关键字呢? def customers(request): search_field = requ ...
- matrox的RAP4G4C12 CXP采集卡软件安装
Hello-FPGA info@hello-fpga.cOM matrox的RAP4G4C12 CXP采集卡软件安装 目录 matrox的RAP4G4C12 CXP采集卡软件安装 4 1 前言 4 2 ...
- 手把手带你快速上手香橙派AIpro
本文分享自华为云社区<香橙派AIpro快速上手指南>,作者:昇腾CANN. 1 前言 作为业界首款基于昇腾深度研发的AI开发板,Orange Pi AIpro无论在外观上.性能上还是技术服 ...