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中插入或删 ...
随机推荐
- C - Dr. Evil Underscores CodeForces - 1285D 二进制
题目大意:n个数,任意整数x对这n个数取异或值,然后使最大值最小. 思路:数据范围最大为pow(2,30);所以考虑二进制的话,最多有30位.对于某一位d,然后考虑数组v中每一个元素的d为是0还是1, ...
- D-Power Products
题目连接: 题解: 根据题目的意思,对每个X进行质因子分解,保存其质因子以及质因子出现的个数,如果两个数的乘积变成一个数的K次幂,那么两个数的质因子的指数之间相加应为k的倍数.保存完毕后,开始遍历,将 ...
- 移动端Vue组件库-Vant学习
全局引入 import Vant from 'vant'; //嫌麻烦就全部一次导出,虽然包会稍微有点大 import 'vant/lib/index.css'; //注意导入全局的这个css,否则布 ...
- python3 xlwt,csv学习
前言 对于抓取一些站点分析然后指纹识别的时候可能用到到它.所以学习下.这里就记录一些最基本的感觉有用的. xlwt 基本创建 demo: #coding=utf- import xlwt yunyin ...
- jmeter DB2数据库连接与操作
1.需要把数据库连接jar包拷贝到 jmeter lib目录下 先创建一个数据库连接配置元件 2.添加jdbc请求(我用的后置处理器) 3.可以通过beanshell 对结果集进行操作 beanshe ...
- 为什么选择python?
Why python? 那些最好的程序员不是为了得到更高的薪水或者得到公众的仰慕而编程,他们只是觉得这是一件有趣的事情. —— Linux 之父 Linux Torvalds 作为一个使用主义的学习者 ...
- java Int类型转为double 类型;string转double
int a=12; double b=(double)a; or double c=Double.valueOf((double)a); string a_s="12"; doub ...
- 科学计算包Numpy
Numpy 用于科学计算的python模块,提供了Python中没有的数组对象,支持N维数组运算.处理大型矩阵.成熟的广播函数库.矢量运算.线性代数.傅里叶变换以及随机数生成等功能,并可与C++.FO ...
- B站百大UP主党妹被黑客勒索!!!
4月27日,哔哩哔哩视频网站的UP主“机智的党妹”发布消息称,自己被黑客勒索了.她的视频表示:“事发突然,我被勒索了,你也有可能继续被诈骗!这种诈骗的页面是由病毒程序自动生成并留在那里的.”根据她的介 ...
- linux--配置开发环境 --Nginx篇
安装: 安装好了话,我们的nginx的目录在: /etc/nginx 启动: sudo service nginx start 然后访问我们的页面就可以看到了我们的界面 然后我们配置我们的域名: 我 ...