ArrayList扩容机制实探
ArrayList初始化
问题:执行以下代码后,这个list的列表大小(size)和容量(capacity)分别是多大?
List<String> list = new ArrayList<>();
答案是:size = 0, capacity = 0,即我们使用无参构造方法创建ArrayList对象时,大小和容量都是为0。
那么如果我继续执行:
for(int i=0;i<100;i++) {
list.add(String.valueOf(i));
}
每次add之后,size和capacity 分别是多少?
答案是:
size = 1, capacity = 10
size = 2, capacity = 10
size = 3, capacity = 10
size = 4, capacity = 10
size = 5, capacity = 10
size = 6, capacity = 10
size = 7, capacity = 10
size = 8, capacity = 10
size = 9, capacity = 10
size = 10, capacity = 10
size = 11, capacity = 15
size = 12, capacity = 15
size = 13, capacity = 15
size = 14, capacity = 15
size = 15, capacity = 15
size = 16, capacity = 22
size = 17, capacity = 22
size = 18, capacity = 22
size = 19, capacity = 22
size = 20, capacity = 22
size = 21, capacity = 22
size = 22, capacity = 22
size = 23, capacity = 33
size = 24, capacity = 33
size = 25, capacity = 33
size = 26, capacity = 33
size = 27, capacity = 33
size = 28, capacity = 33
size = 29, capacity = 33
size = 30, capacity = 33
size = 31, capacity = 33
size = 32, capacity = 33
size = 33, capacity = 33
size = 34, capacity = 49
size = 35, capacity = 49
size = 36, capacity = 49
size = 37, capacity = 49
size = 38, capacity = 49
size = 39, capacity = 49
size = 40, capacity = 49
size = 41, capacity = 49
size = 42, capacity = 49
size = 43, capacity = 49
size = 44, capacity = 49
size = 45, capacity = 49
size = 46, capacity = 49
size = 47, capacity = 49
size = 48, capacity = 49
size = 49, capacity = 49
size = 50, capacity = 73
size = 51, capacity = 73
size = 52, capacity = 73
size = 53, capacity = 73
size = 54, capacity = 73
size = 55, capacity = 73
size = 56, capacity = 73
size = 57, capacity = 73
size = 58, capacity = 73
size = 59, capacity = 73
size = 60, capacity = 73
size = 61, capacity = 73
size = 62, capacity = 73
size = 63, capacity = 73
size = 64, capacity = 73
size = 65, capacity = 73
size = 66, capacity = 73
size = 67, capacity = 73
size = 68, capacity = 73
size = 69, capacity = 73
size = 70, capacity = 73
size = 71, capacity = 73
size = 72, capacity = 73
size = 73, capacity = 73
size = 74, capacity = 109
size = 75, capacity = 109
size = 76, capacity = 109
size = 77, capacity = 109
size = 78, capacity = 109
size = 79, capacity = 109
size = 80, capacity = 109
size = 81, capacity = 109
size = 82, capacity = 109
size = 83, capacity = 109
size = 84, capacity = 109
size = 85, capacity = 109
size = 86, capacity = 109
size = 87, capacity = 109
size = 88, capacity = 109
size = 89, capacity = 109
size = 90, capacity = 109
size = 91, capacity = 109
size = 92, capacity = 109
size = 93, capacity = 109
size = 94, capacity = 109
size = 95, capacity = 109
size = 96, capacity = 109
size = 97, capacity = 109
size = 98, capacity = 109
size = 99, capacity = 109
size = 100, capacity = 109
从中看出了规律:
即:ArrayList无参初始化是,容量是0,往list里面添加一个元素,容量开始扩容,扩容大小是10,当我的size到达10之后,再继续添加时,容量是拿当前的容量乘以1.5倍,舍去小数取整,即为新容量大小。
那如果继续无限添加元素呢,答案是:
拿最后一次扩容的容量与 整型最大值 - 8比较,如果是大于的话,取整型最大值(即:2^31 -1),如果是小于,则取整型最大值 - 8
ArrayList扩容源码如下:
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:
elementData = Arrays.copyOf(elementData, newCapacity);
}
capacity 是list的私有属性,也没有提供相关的方法获取这个值,不过我们可以通过反射来获取这个值:
public int getArrayListCapacity(List arrayList) {
Class<ArrayList> arrayListClass = ArrayList.class;
int capacity = 0;
try {
Field field = arrayListClass.getDeclaredField("elementData"); //获取 elementData 字段
field.setAccessible(true);// 设置为可访问
Object[] objects = (Object[])field.get(arrayList);
//返回当前ArrayList实例的容量值
capacity = objects.length;
} catch (Exception e) {
e.printStackTrace();
capacity = -1;
}
return capacity;
}
测试代码:
List<String> list = new ArrayList<>();
System.out.println(getArrayListCapacity(list));
for(int i=0;i<100;i++) {
list.add(String.valueOf(i));
System.out.println("size = " + list.size() + ", capacity = " + getArrayListCapacity(list));
}
ArrayList扩容机制实探的更多相关文章
- ArrayList扩容机制
一.先从 ArrayList 的构造函数说起 ArrayList有三种方式来初始化,构造方法源码如下: 1 /** 2 * 默认初始容量大小 3 */ 4 private static final i ...
- ArrayList扩容机制以及底层实现
简介 来源:博客园 作者:吾王彦 博客链接:https://www.cnblogs.com/qinjunlin/p/13724987.html ArrayList动态数组,是 java 中比较常 ...
- ArrayList源码解析(二)自动扩容机制与add操作
本篇主要分析ArrayList的自动扩容机制,add和remove的相关方法. 作为一个list,add和remove操作自然是必须的. 前面说过,ArrayList底层是使用Object数组实现的. ...
- ArrayList的扩容机制
一.ArrayList的扩容机制 1.扩容的计算方式是向右位移,即:newSize = this.size + (this.size>>1).向右位移,只有在当前值为偶数时,才是除以2:奇 ...
- 浅谈JAVA中HashMap、ArrayList、StringBuilder等的扩容机制
JAVA中的部分需要扩容的内容总结如下:第一部分: HashMap<String, String> hmap=new HashMap<>(); HashSet<Strin ...
- 【数组】- ArrayList自动扩容机制
不同的JDK版本的扩容机制可能有差异 实验环境:JDK1.8 扩容机制: 当向ArrayList中添加元素的时候,ArrayList如果要满足新元素的存储超过ArrayList存储新元素前的存储能力, ...
- 关于ArrayList的扩容机制
关于ArrayList的扩容机制 ArrayList作为List接口常用的一个实现类,其底层数据接口由数组实现,可以保证O(1) 复杂度的随机查找, 在增删效率上不如LinkedList,但是在查询效 ...
- Java ArrayList自动扩容机制
动态扩容 1.add(E e)方法中 ① ensureCapacityInternal(size+1),确保内部容量,size是添加前数组内元素的数量 ② elementData[size++] ...
- 浅谈 ArrayList 及其扩容机制
浅谈ArrayList ArrayList类又称动态数组,同时实现了Collection和List接口,其内部数据结构由数组实现,因此可对容器内元素实现快速随机访问.但因为ArrayList中插入或删 ...
随机推荐
- 模拟电磁曲射炮_H题 方案分析【2019年电赛】【刘新宇qq522414928】
请查看我的有道云笔记: 文档:电磁曲射炮分析.note链接:http://note.youdao.com/noteshare?id=26f6b6febc04a8983d5efce925e92e21
- <algorithm>中sort()函数的用法
先说一下,本篇文章我没有讲sort()实现排序的原理,我写在另一篇文章中了,如果想了解的话,可以看一下,附上链接:https://www.cnblogs.com/buanxu/p/12772700.h ...
- vue 开发规范
本文档为前端 vue 开发规范 规范目的 命名规范 结构化规范 注释规范 编码规范 CSS 规范 规范目的 为提高团队协作效率 便于后台人员添加功能及前端后期优化维护 输出高质量的文档 命名规范 为了 ...
- 使用Spring Boot搭建你的第一个应用程序
文章目录 依赖配置 main程序配置 MVC配置 安全配置 存储 Web 页面和Controller 异常处理 测试 结论 Spring Boot是Spring平台的约定式的应用框架,使用Spring ...
- atom 之 前端必备插件
一. 语法支持 1. Language-label Ø ES2016.ESNext.JXS语法扩展 2. Language-postcss Ø Postcss语法高亮 二. 自动补全 1. Autoc ...
- sed 和 awk
sed [选项] 动作 文件 -n #取消默认输出 ,有n必须要有p,有p加了n才不会有默认输出 -i #真正的替换,修改 -r #支持扩展正则 (* [A-z] '|') 内部命令: p #打印 - ...
- BigDecimal 01 - 在JAVA中怎么比较Double类型数据的大小?
2019独角兽企业重金招聘Python工程师标准>>> 非整型数,运算由于精度问题,可能会有误差,建议使用BigDecimal类型! double a = 0.001; doub ...
- vue elementui table 双击单元格实现编辑,聚焦,失去焦点,显示隐藏input和span
<el-table :data="tableData" class="tb-edit" style="width: 100%" ref ...
- windows下git commit使用gvim编辑器
安装gvim 下载安装包:ftp://ftp.vim.org/pub/vim/pc/gvim80-586.exe 安装后将安装路径添加到环境变量Path中 设置编码支持中文 在安装路径下的_vimrc ...
- Math.Round和四舍五入
Math.Round方法并不是像想象中的四舍五入, 可以从下面的输出结果看出来: Math.Round(3.44, 1); //Returns 3.4. Math.Round(3.45, 1); // ...