java 增长因子_Java ArrayList的扩容因子为什么是1.5?
ArrayList底层是数组elementData,用于存放插入的数据。初始大小是0,当有数据插入时,默认大小DEFAULT_CAPACITY = 10。
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* will be expanded to DEFAULT_CAPACITY when the first element is added.
*/
transient Object[] elementData; // non-private to simplify nested class access
什么时候进行扩容?
当插入数据,导致size + 1 > elementData.length,也就是需要从容量超过目前数组长度时,需要进行扩容。
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!! // add一个元素时,size + 1
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private static int calculateCapacity(Object[] elementData, int minCapacity) { // 计算新容量
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { // 代表elementData数组还是一个空数组,没有任何数据
return Math.max(DEFAULT_CAPACITY, minCapacity); // elementData为空时,会扩容到DEFAULT_CAPACITY = 10和minCapacity的最大值,而minCapacity在插入数据时第一次值为1(size + 1 = 1),会扩容为10
}
return minCapacity;
}
如何扩容?
新数组容量为旧数组的1.5倍:newCapacity = 1.5 * oldCapacity ,并且将旧数组内容通过Array.copyOf全部复制到新数组。此时,size还未真正+1,新旧数组长度(size一致),不过容量不同。
把这里的系数1.5,称作扩容因子k = newCapacity / oldCapacity
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
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);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
扩容因子k为何是1.5?
下面举一组对比的例子,取不同扩容因子和初始容量的内存分配情况,当然容量不可能是4,只是方便说明:
k = 2, capacity = 4
0123
01234567
0123456789101112131415
012345678910111213141516171819202122232425262728293031
0123...
k = 1.5, capacity = 4
0123
012345
012345678
0123456789101112
...
k=1.5时,就能充分利用前面已经释放的空间。如果k >= 2,新容量刚刚好永远大于过去所有废弃的数组容量。
为什么不取扩容固定容量呢?
扩容的目的需要综合考虑这两种情况:
扩容容量不能太小,防止频繁扩容,频繁申请内存空间 + 数组频繁复制
扩容容量不能太大,需要充分利用空间,避免浪费过多空间;
而扩容固定容量,很难决定到底取多少值合适,取任何具体值都不太合适,因为所需数据量往往由数组的客户端在具体应用场景决定。依赖于当前已经使用的量 * 系数, 比较符合实际应用场景。
比如,我现在已经用到一个数组100的容量,接下来很可能会有这个数量级的数据需要插入。
为什么是1.5,而不是1.2,1.25,1.8或者1.75?
因为1.5 可以充分利用移位操作,减少浮点数或者运算时间和运算次数。
// 新容量计算
int newCapacity = oldCapacity + (oldCapacity >> 1);
java 增长因子_Java ArrayList的扩容因子为什么是1.5?相关推荐
- java list负载_java集合的扩容和负载因子的总结
List 元素是有序的.可重复 ArrayList.Vector默认初始容量为10 Vector:线程安全,但速度慢 底层数据结构是数组结构 加载因子为1:即当 元素个数 超过 容量长度 时,进行扩容 ...
- java 遍历方法_Java ArrayList遍历的3种方法
首页 > 基础教程 > 集合框架 > ArrayList类 Java ArrayList遍历的3种方法 1. Iterator方法遍历 for(Iterator it2 = list ...
- java sublist 用法_Java ArrayList subList() 使用方法及示例
Java ArrayList subList() 使用方法及示例 Java ArrayList subList()方法提取一部分arraylist并将其返回. subList()方法的语法为: arr ...
- java isempty用法_Java ArrayList isEmpty() 使用方法及示例
Java ArrayList isEmpty() 使用方法及示例 Java ArrayList isEmpty()方法用于检查arraylist是否为空. 该isEmpty()方法的语法为: arra ...
- java list原理_Java中ArrayList实现原理
前言 这个分类中,将会写写Java中的集合.集合是Java中非常重要而且基础的内容,因为任何数据必不可少的就是该数据是如何存储的,集合的作用就是以一定的方式组织.存储数据.这里写的集合,一部分是比较常 ...
- java基础巩固-宇宙第一AiYWM:为了维持生计,多高(多线程与高并发)_Part9~整起(单双列集合们、ArrayList 的扩容机制、HashMap、ConcurrentHashMap )
再进入正文之前,先看看集合相关操作的时间复杂度: 本故事源自于~ 开唠: PART0: 为什么突然蹦出集合这个玩意,就是因为咱们基础那里学的"数组"不够用~: 数组一般用来保存一组 ...
- Java之List系列--ArrayList扩容的原理
原文网址:Java之List系列--ArrayList扩容的原理_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍Java的ArrayList是如何进行扩容的.即:扩容的机制. 重要大小 类 初 ...
- java list原理_Java集合:ArrayList的实现原理
目录: 一. ArrayList概述: ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存. ArrayList不是线程安全的,只能用在单 ...
- 【java】为什么 HashMap 的加载因子是0.75?
1.概述 转载:为什么 HashMap 的加载因子是0.75? 有很多东西之前在学的时候没怎么注意,笔者也是在重温HashMap的时候发现有很多可以去细究的问题,最终是会回归于数学的,如HashMap ...
最新文章
- JS中编写函数去除HTML标签,js函数获取html中className所在的内容并去除标签
- 使用指针做函数返回值
- node重命名文件名_利用Node.js对文件进行重命名
- Week1 Team Homework #2 from Z.XML-Introduction of team member with photos
- IDEA中无法识别servlet类或找不到javax.servlet.*
- linux脚本实现复制,Shell脚本实现复制文件到多台服务器的代码分享
- 闯过这 54 关,点亮你的 Git 技能树 (五) - 完结篇
- verilog实现多周期处理器之——(六)简单算数操作指令的实现
- Linux命令——lsb_release
- Flink+Alink,当大数据遇见机器学习! 博文视点Broadview 前天
- Linux系统启动过程分析
- SQL语句- 条件查询
- html网页自动提示框代码,多种网页弹出窗口代码
- Guass-seidel 迭代法 matlab实现
- Angular—生命周期函数
- macOS开启高性能模式
- cad哪个版本最好用?思路提供
- 2022年系统集成项目管理工程师考试知识点:项目成本管理
- 硬盘修复真经 误区、缺陷、参数与低格
- IOT设备情况数据分析
热门文章
- 华为AppCube入选Forrester《中国低代码平台市场分析报告》
- 授人以渔:stm32资料查询技巧
- 【华为云技术分享】从自建MongoDB聊聊云数据库MongoDB的蓬勃张力
- 华为云MVP:来自工业制造领域的微服务与云平台实践
- 基于netty4.x开发时间服务器
- 江苏小高考计算机操作题软件,江苏小高考现神题:求微信启动画面的拍摄时间...
- opengl学习笔记(六)
- LeetCode-116. 填充每个节点的下一个右侧节点指针
- LeetCode-567:字符串的排列
- php代码实现tp5监听队列,thinkPHP5的队列使用