【数组】- ArrayList自动扩容机制
不同的JDK版本的扩容机制可能有差异 实验环境:JDK1.8
扩容机制:
当向ArrayList中添加元素的时候,ArrayList如果要满足新元素的存储超过ArrayList存储新元素前的存储能力,ArrayList会增强自身的存储能力,已达到存储新元素的要求
ArrayList:本质通过内部维护的数组对象进行数据存储
①:分析ArrayList的add(E)方法
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
分析:add方法首先通过ensureCapacityInternal()方法确保当前ArrayList维护的数组具有存储新元素的能力,经过处理之后将元素存储在数组elementData的尾部 elementData:ArrayList真正用于存储元素的数组
②:分析ensureCapacityInternal方法
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
分析:ensureCapacityInternal判断ArrayList默认的元素存储数据是否为空,为空则设置最小要求的存储能力为必要存储的元素和默认存储元素个数的两个数据之间的最大值,然后调用ensureExplicitCapacity方法实现这种最低要求的存储能力
注意:ArrayList的存储空间并不是需要一个创建一个,而是分阶段性的创建,一般会预留存储空间。 例如,如果ArrayList需要存储10个元素,恰好ArrayList只能存储6个元素,剩余4个元素无法存储,ArrayList可能会一次性扩展10个元素,这种ArrayList就有20个元素的存储能力,在存储能力范围内,下次再存放元素,就不需要再次扩容
③:分析ensureExplicitCapacity方法:
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
分析:如果最低要求的存储能力>ArrayList已有的存储能力,这就表示ArrayList的存储能力不足,因此需要调用 grow();方法进行扩容 ④:分析grow()方法
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);
}
分析:当ArrayList扩容的时候,首先会设置新的存储能力为原来的1.5倍
int newCapacity = oldCapacity + (oldCapacity www.michenggw.com>> 1);
如果扩容之后还是不能满足要求则MAX_ARRAY_SIZE比较,求取最大值, 如果MAX_ARRAY_SIZE大小的能力还是不能满足则通过hugeCapacity()方法获取ArrayList能允许的最大值:
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
从hugeCapacity方法看出,ArrayList最大的存储能力:存储元素的个数为整型的范围。 确定ArrayList扩容之后最新的可存储元素个数时,调用 elementData = Arrays.copyOf(elementData, newCapacity); 实现elementData数组的扩容,整个流程就是ArrayList的自动扩容机制工作流程
扩展: ArrayList的自动扩容机制底层借助于System实现
public static native void arraycopy
(Object src, int srcPos,
Object dest, int destPos,
int length);
arraycopy标识为native意味JDK的本地库,不可避免的会进行IO操作,如果频繁的对ArrayList进行扩容,毫不疑问会降低ArrayList的使用性能,因此当我们确定添加元素的个数的时候,我们可以事先知道并指定ArrayList的可存储元素的个数,这样当我们向ArrayList中加入元素的时候,就可以避免ArrayList的自动扩容,从而提高ArrayList的性能
ArrayList含参构造函数:初始化时指定存储元素的能力:
public ArrayList(int initialCapacity) {
if (initialCapacity www.dasheng178.com> 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException(
"Illegal Capacity: "+initialCapacity);
}
【数组】- ArrayList自动扩容机制的更多相关文章
- Java ArrayList自动扩容机制
动态扩容 1.add(E e)方法中 ① ensureCapacityInternal(size+1),确保内部容量,size是添加前数组内元素的数量 ② elementData[size++] ...
- ArrayList源码解析(二)自动扩容机制与add操作
本篇主要分析ArrayList的自动扩容机制,add和remove的相关方法. 作为一个list,add和remove操作自然是必须的. 前面说过,ArrayList底层是使用Object数组实现的. ...
- 关于ArrayList的扩容机制
关于ArrayList的扩容机制 ArrayList作为List接口常用的一个实现类,其底层数据接口由数组实现,可以保证O(1) 复杂度的随机查找, 在增删效率上不如LinkedList,但是在查询效 ...
- 浅谈 ArrayList 及其扩容机制
浅谈ArrayList ArrayList类又称动态数组,同时实现了Collection和List接口,其内部数据结构由数组实现,因此可对容器内元素实现快速随机访问.但因为ArrayList中插入或删 ...
- ArrayList的扩容机制
一.ArrayList的扩容机制 1.扩容的计算方式是向右位移,即:newSize = this.size + (this.size>>1).向右位移,只有在当前值为偶数时,才是除以2:奇 ...
- HashMap自动扩容机制源码详解
一.简介 HashMap的源码我们之前解读过,数组加链表,链表过长时裂变为红黑树.自动扩容机制没细说,今天详细看一下 往期回顾: Java1.7的HashMap源码分析-面试必备技能 Java1.8的 ...
- ArrayList动态扩容机制
初始化:有三种方式 1.默认的构造器,将会以默认的大小来初始化内部的数组:public ArrayList(); 2.用一个ICollection对象来构造,并将该集合的元素添加到ArrayList: ...
- ArrayList-源码分析-自动扩容机制
ArrayList类: public class ArrayList....{ ...... private static final int DEFAULT_CAPACITY = 10; //默认容 ...
- 学习ArrayList的扩容机制
基于jdk8 1.首先我们看new ArrayList中 public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDA ...
随机推荐
- windows下如何将Python文件打包成.exe可执行文件
在使用Python做开发的时候,时不时会给自己编写了一些小工具辅助自己的工作,但是由于开发依赖环境问题,多数只能在自己电脑上运行,拿到其它电脑后就没法运行了.这显得很不方便,不符合我们的初衷,那么有没 ...
- shell 判断日期间隔及润年
#!/bin/bash test.sh until echo "----------------------------------" echo "请输入您的选择:&qu ...
- Delphi 中的 RectTracker - 原创
本文算是副产品,正品是利用 FFmpeg 从任意视频中生成GIF片段的小程序,写完了就发. V2G 正品已出炉,虽然不大像样,但好歹是能用,请见:用 Delphi 7 实现基于 FFMS2 的视频转 ...
- 【ZABBIX】ZABBIX3.2升级3.4
小贴士 1.停止zabbix服务 service zabbix_server stop service zabbix_agentd stop /usr/local/zabbix/sbin/zabbix ...
- hdu - 6277,2018CCPC湖南全国邀请赛B题,找规律,贪心找最优.
题意: 给出N个小时,分配这些小时去写若干份论文,若用1小时写一份论文,该论文会被引用A次,新写一篇论文的话,全面的论文会被新论文引用一次. 找最大的H,H是指存在H遍论文,而且这些论文各被引用大于H ...
- 剑指 Offer——数字在排序数组中出现的次数
1. 题目 2. 解答 时间复杂度为 \(O(n)\) 的算法,顺序遍历数组,当该数字第一次出现时开始记录次数. class Solution { public: int GetNumberOfK(v ...
- YQCB冲刺周第三天
团队讨论照片 今天的任务为实现由用户记录一条数据,向数据库中添加一条数据. 遇到的问题为获取单选框.下拉菜单的参数.
- UI分析之石家庄铁道大学官网
点击进入石家庄铁道大学的官方网站,首先映入眼帘的是“石家庄铁道大学”七个大字,配以蓝色背景和学校的俯瞰图,给人一种严谨又不失清新的感觉. 学校的网站首页界面主要有九个界面,分别是网站首页,学校概况,组 ...
- [pascal入门]数组
一.本节目标 本节我们将要讲述数组.本节目标: 一维数组 二维数组 字符数组 二.一维数组 我们通过一个案例来简单的理解数组.班主任要计算班级里面50个同学数学成绩的平均成绩,道理上讲这是一个比较简单 ...
- 一次WebSphere性能问题诊断过程
一次接到用户电话,说某个应用在并发量稍大的情况下就会出现响应时间陡然增大,同时管理控制台的响应时间也很慢,几乎无法进行正常工作. 赶到现场后,查看平台版本为Webshpere6.0.2.29,操作系统 ...