ArrayList扩容分析
一段java代码
String e = "q3234v";
List<String> list = new ArrayList<String>();
for (int i = 0; i < 25; i++) {
list.add(e);
}
执行这段代码,list会扩容几次
查看ArrayList的add方法,在添加元素之前会执行ensureCapacityInternal方法
这个时候size为0
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
继续看ensureCapacityInternal方法,DEFAULT_CAPACITY的值为10,此时minCapacity为1
private static final int DEFAULT_CAPACITY = 10;
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
这时候执行:ensureExplicitCapacity
此时minCapacity的值为10,接下来执行扩容方法
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int 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:
System.out.println(minCapacity+"------"+newCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
minCapacity的值为10
新空间大小的值为 0+0>>1 = 0
所以第一次扩容完 后新空间大小为10
接下当list.add()执行到第11次的时候
minCapacity=11
newCapacity = 10+10>>1 = 15(1010>>1 = 101= 5)
i执行到16的时候,此时又发现空间不够了
minCapacity=16
newCapacity = 15+15>>1 = 22(1111>>1 = 7)
所以容量到25还需要再执行一次扩容
一共会执行4次扩容
这时候可能会发现在扩容的时候会执行 elementData = Arrays.copyOf(elementData, newCapacity)方法
所以为了减少copyOf的操作
在大概知道List的长度的情况下,在创建的时候应该给一个容量,在容量不够的情况下才会执行扩容操作
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
ArrayList扩容分析的更多相关文章
- ArrayList的分析(转)
一. ArrayList概述: ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存. ArrayList不是线程安全的,只能用在单线程环境 ...
- ArrayList 扩容原理
面试中经常问到的问题之一就是List的扩容机制了,他是怎么做到扩容的,大家都能答出来底层是数组,复制一个数组来扩容,但是再具体一点来说,大家就不知道该怎么说了,如果不看源码说这么多确实就差不多了,但是 ...
- ArrayList扩容机制
一.先从 ArrayList 的构造函数说起 ArrayList有三种方式来初始化,构造方法源码如下: 1 /** 2 * 默认初始容量大小 3 */ 4 private static final i ...
- 都说新的Arraylist 扩容是(1.5倍+1) 看了1.8的源代码发现不是这么回事
都说新的Arraylist 扩容是(1.5倍+1) 看了1.8的源代码发现不是这么回事 就用下面这段代码在jdk的三个版本运行看了下效果 import java.lang.reflect.Field; ...
- 分享知识-快乐自己:都说新的Arraylist 扩容是(1.5倍+1) 看了1.8的源代码发现不是这么回事
都说新的Arraylist 扩容是(1.5倍+1) 看了1.8的源代码发现不是这么回事 就用下面这段代码在jdk的三个版本运行看了下效果: import java.lang.reflect.Field ...
- coding++:都说新的Arraylist 扩容是(1.5倍+1) 看了1.8的源代码发现不是这么回事
都说新的Arraylist 扩容是(1.5倍+1) 看了1.8的源代码发现不是这么回事 就用下面这段代码在jdk的三个版本运行看了下效果: import java.lang.reflect.Fiel ...
- ArrayList扩容机制实探
ArrayList初始化 问题:执行以下代码后,这个list的列表大小(size)和容量(capacity)分别是多大? List<String> list = new ArrayList ...
- external-resizer 源码分析/pvc 扩容分析
kubernetes ceph-csi分析目录导航 基于tag v0.5.0 https://github.com/kubernetes-csi/external-resizer/releases/t ...
- ArrayList原理分析(重点在于扩容)
首先,ArrayList定义只定义类两个私有属性: /** * The array buffer into which the elements of the ArrayList are stored ...
随机推荐
- 关于开发APP接口版本不兼容的问题
关于 APP接口版本兼容的问题. iOS和android 要不断开发新版本,很多服务端开发都是在以前接口的逻辑上进行修改. 新的APP和接口开发后,接口如何兼容老的APP? 有的公司 每次发布完APP ...
- React Redux 与胖虎
这是一篇详尽的 React Redux 扫盲文. 对 React Redux 已经比较熟悉的同学可以直接看 <React Redux 与胖虎他妈>. 是什么 React Redux 是 R ...
- better-scroll 介绍
碰到一个项目,应该遵守两大规则: 1. 不要让项目产生过多的第三方依赖 2. 增强组件的应用率 尽可能的将东西写在组件里面,尽可能的将数据写活,通过组件通信来进行数据转换,用到的依赖处理,我们可以通过 ...
- airflow当触发具有多层subDAG的任务的时候,出现[Duplicate entry ‘xxxx’ for key dag_id]的错误的问题处理
当触发一个具有多层subDAG的任务时,会发现执行触发的task任务运行失败,但是需要触发的目标DAG已经在运行了,dag log 错误内容: [2019-11-21 17:47:56,825] {b ...
- nginx目录及配置语法
一.Nginx安装目录 1.查看安装目录. 采用yum的方式安装,其实都是安装的一个一个的 pm 包,故可采用如下命令查看 rpm -ql nginx 遵循了 rpm 包管理规范. 2.安装目录详解 ...
- 计算机组成原理 — CPU 中央处理器
目录 文章目录 目录 前文列表 逻辑电路部件 组合逻辑电路 时序逻辑电路 阵列逻辑电路 中央处理器(CPU) 控制单元(控制器) 运算单元(运算器) 存储单元(寄存器组和片内缓存) CPU 的工作原理 ...
- AES256位加密
目录 1. 算法简介 2. 算法流程 2.1 扩展密钥 2.2 轮密钥加 2.3 字节代替 2.4 行位移 2.5 列混淆 3. 总结 附录A 运算示例 1.算法简介高级加密标准(英 ...
- 仿flash运动框架
github地址: [https://github.com/linxd5/pictureShow] PS: 新建一个github项目很简单,只要new一个repo,后面按照提示做就可以了~ 项目思路: ...
- Mysql:常用操作(导入数据,用户授权,远程连接授权,设置通信缓冲区的最大长度)
1.导入数据命令: mysql --host=localhost --port=3306 --user=root --password=hnsjt_lwsj@2018 szyszx_20180515- ...
- OnCustomDraw
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, &CMyListCtrl::OnNMCustomdraw) ON_NOTIFY : Comes from a child co ...