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数组实现的. ...
随机推荐
- PHP程序员的能力水平层次
PHP程序员的能力水平层次 之前看过很多篇关于服务端工程师和PHP开发者的能力模型介绍,每篇都对能力有侧重点. 下面我们来详细谈谈以开发能力为基准点的PHP程序员的能力水平层次. 层层递进 1.功能开 ...
- POJ2749 Building roads
嘟嘟嘟 最近把21天漏的给不上. 今天重温了一下2-SAT,感觉很简单.就是把所有条件都转化成如果--必然能导出--.然后就这样连边建图,这样一个强连通分量中的所有点必然都是真或者假.从而根据这个点拆 ...
- iptables 端口转发规则
玩 vps 的经常要用到端口转发用以实现更快的速度.比如 ovh 机房的网络我这里访问非常慢,用远程桌面会吐血的类型.所以就会用其他的线路作为跳板,比如洛杉矶,香港之类的.再比如如果需要一个日本 ip ...
- 【window】git安装教程
相关链接:https://blog.csdn.net/nly19900820/article/details/73379854 作者:smile.轉角 QQ:493177502
- 吴恩达课后作业学习2-week1-1 初始化
参考:https://blog.csdn.net/u013733326/article/details/79847918 希望大家直接到上面的网址去查看代码,下面是本人的笔记 初始化.正则化.梯度校验 ...
- SSH远程SOLARIS11时被拒绝
在虚拟机中新安装的solaris11,安装过程中配置了静态IP地址用以方便ssh连接,使用root用户ssh连接时,密码没有错,但总是提示密码被拒绝,连接established 代表是通的,telne ...
- <STL源码剖析>配置器
1.stl六大部件 容器:各种数据结构,包括vector,list,deque,set,map等等 算法:各种常用算法,sort,search 迭代器:容器和算法之间的粘合器 防函数:类似于函数 配接 ...
- BZOJ1023 SHOI2008 仙人掌图 仙人掌、单调队列
传送门 求仙人掌的直径,可以由求树的直径进行拓展,只需要在环上特殊判断. 沿用求树的直径的DP,对于一条不在任何环内的边,直接像树的直径一样转移,然后考虑环的影响. 设环长为\(cir\),在\(df ...
- 多线程-Callable、Future、FutureTask
我们普遍知道的创建线程的方式有两种,一种是继承Thread,一种是实现Runnable接口.这两种方式都无法获取任务执行完后的结果,并发包提供了Callable 类能够得到任务执行完的结果. 为何需要 ...
- [翻译] 使用 .NET Core 3.0 创建一个 Windows 服务
原文: .NET Core Workers as Windows Services 在 .NET Core 3.0 中,我们引入了一种名为 Worker Service 的新型应用程序模板.此模板旨在 ...