ArrayList的扩容机制
一、ArrayList的扩容机制
1、扩容的计算方式是向右位移,即:newSize = this.size + (this.size>>1)。向右位移,只有在当前值为偶数时,才是除以2;奇数时是抹去最后一位,也就是先减1,然后除以2;附上源码,如下图:

2、扩容的上限:ArrayList的长度并不是没有限制的,它的默认最大长度值是,Integer.MAX_VALUE-8,但是可以突破到 Integer.MAX_VALUE。所以请注意:如果到达ArrayList的默认最大值的时候,扩容不再是1.5倍,而是只增加一个字节,长度达到Integer.MAX_VALUE,如下图的hugeCapacity()方法。此后再进行添加操作,容量是无法扩充了,仍然是Integer.MAX_VALUE,应该无法再添加对象,有兴趣的童鞋可以试试~~~

个人对ArrayList的极限测试,初始容量值不能过大(容易堆内存溢出),也不能太小(扩容次数太多,性能影响太大),另外需要调整虚拟机内存大小,下图就是我的代码:

ps.
1、这个位置有点意思 arr.add(Integer.MAX_VALUE+1),本来要放的是Integer类型的,但是括号里按理说已经扩充至long了,编译时不报错。实际结果是变成了-2147483648,也就是Integer.MIN_VALUE,一下子从九重天跌入十八层地狱。。。。
2、实际上,大家可以试一下,System.out.println(2147483647+1),结果是 -2147483648。除非对其中一个数进行强转成long类型,或者表示为long类型。换句话说,内存类型相对固定(如int),内存占用的位数并不改变,当发生+1操作时,只是在数值上简单+1,当值达到Integer.MAX_VALUE时,最高位是0,再+1高位变成1,也就是最小值,所以不论int类型参数之间不论怎么做加减法运算,永远都是固定的内存空间里发生的变化,取值范围永远在Integer的最大值和最小值的完全闭区间内,因为只有这么大的空间。如果是int碰上long,小的自然服从大的,内存空间必定要发生变化(底层实现决定)。
二、ArrayList容量之最佳实践
扩容是有成本的,要经历System.arrayCopy(),数组越长成本越高。所以最佳实践是:知道即将放入ArrayList容器的对象数量时,最好能指定合理的初始容量capacity(警告:size和capacity的区别:capacity,即容量,size,容器所盛放对象的数量。通俗的说,假如一个矿泉水瓶(也就是容器,如ArrayList、HashMap)的容量值为600ml,盛放的水量(size)为550ml)。
ps.集合框架类,有时候也叫容器类,因为它们是存放其他对象(水)的对象(矿泉水瓶)。个人觉得,从白盒的角度看,LinkedList(链表)算不得容器,而更像是火车、地铁车厢之类的链式结构的东西,相互之间环环相扣;但是从黑盒的角度来看,把LinkedList称为容器好像也没毛病,因为看起来可以存放东西。
ArrayList的扩容机制的更多相关文章
- 关于ArrayList的扩容机制
关于ArrayList的扩容机制 ArrayList作为List接口常用的一个实现类,其底层数据接口由数组实现,可以保证O(1) 复杂度的随机查找, 在增删效率上不如LinkedList,但是在查询效 ...
- 浅谈 ArrayList 及其扩容机制
浅谈ArrayList ArrayList类又称动态数组,同时实现了Collection和List接口,其内部数据结构由数组实现,因此可对容器内元素实现快速随机访问.但因为ArrayList中插入或删 ...
- 【数组】- ArrayList自动扩容机制
不同的JDK版本的扩容机制可能有差异 实验环境:JDK1.8 扩容机制: 当向ArrayList中添加元素的时候,ArrayList如果要满足新元素的存储超过ArrayList存储新元素前的存储能力, ...
- Java ArrayList自动扩容机制
动态扩容 1.add(E e)方法中 ① ensureCapacityInternal(size+1),确保内部容量,size是添加前数组内元素的数量 ② elementData[size++] ...
- ArrayList动态扩容机制
初始化:有三种方式 1.默认的构造器,将会以默认的大小来初始化内部的数组:public ArrayList(); 2.用一个ICollection对象来构造,并将该集合的元素添加到ArrayList: ...
- 学习ArrayList的扩容机制
基于jdk8 1.首先我们看new ArrayList中 public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDA ...
- 小白也能看懂的ArrayList的扩容机制
来,话不多说进入正题!我们下面用最简单的代码创建ArrayList并添加11个元素,并 一 一 讲解底层源码:在说之前,给大家先普及一些小知识: >ArrayList底层是用数组来实现的 > ...
- 送分题,ArrayList 的扩容机制了解吗?
1. ArrayList 了解过吗?它是啥?有啥用? 众所周知,Java 集合框架拥有两大接口 Collection 和 Map,其中,Collection 麾下三生子 List.Set 和 Queu ...
- ArrayList源码解析(二)自动扩容机制与add操作
本篇主要分析ArrayList的自动扩容机制,add和remove的相关方法. 作为一个list,add和remove操作自然是必须的. 前面说过,ArrayList底层是使用Object数组实现的. ...
随机推荐
- CAS跳转流程
场景一: 用户先访问广告合同管理系统ADM,去投放广告,之后又去资产系统AMS,查看资产信息. 访问ADM时,用户需要先去CAS登录,之后访问AMS时 1.访问广告合同管理系统ADM: 2.访问AMS ...
- Anaconda的下载与安装
1.下载地点: 支持国产:https://mirrors.tuna.tsinghua.edu.cn/ Anaconda官网:https://www.anaconda.com/download/ 2.下 ...
- 51nod 省选联测 R2
51nod 省选联测 R2 上场的题我到现在一道都没A,等哪天改完了再写题解吧,现在直接写第二场的. 第二场比第一场简单很多(然而这并不妨碍我不会做). A.抽卡大赛:http://www.51nod ...
- 通俗易懂的php多线程解决方案
我们在做项目的时候,有些需求,特别是数据的响应处理需要花费大量的时间,由于php是一个短生命周期的脚本语言,到了默认的30秒,php的数据处理还没完成,php的生命周期就结束了.这时需要使用异步并发处 ...
- Spring Security(九):2.4.4 Checking out the Source(检查来源)
Since Spring Security is an Open Source project, we’d strongly encourage you to check out the source ...
- Flask 框架 重定向,捕获异常,钩子方法及使用jsonify在网页返回json数据
Flask 框架中常用到重定向方法来实现路由的跳转 ,路由跳转又分为站内跳转和站外跳转 常用的站内跳转方法为url_for 而常用的站外跳转为redirect 在这里提示一下: 在使用两种方法是须调 ...
- P2251 质量检测--洛谷luogu
传送门 题目描述 为了检测生产流水线上总共N件产品的质量,我们首先给每一件产品打一个分数A表示其品质,然后统计前M件产品中质量最差的产品的分值Q[m] = min{A1, A2, ... Am},以及 ...
- D. Artsem and Saunders
一个变换题 给定f(x),[1,n]->[1,n] 构造g(x),h(x)满足: g(h(x))=x [1,n]->[1,m] h(g(x))=f(x) [1,m]->[1,n] 根 ...
- macOS下appstore提示未能完成该操作的解决办法
macOS下App Store下载软件,提示:未能完成该操作.(com.apple.commerce.client 错误 500.) 解决办法: 在终端输入 defaults write com.ap ...
- WPF效果(GIS二维篇)
距离上次发东西已经过去了貌似不知多少天了,突然发现自己懒得总结了.这毛病感觉不好,还得写点东西来充实一下自己,不然这样整天浑浑噩噩的过日子,也太平淡了,不管怎么说,起码得给自己的经历留下点东西吧.闲话 ...