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数组实现的. ...
随机推荐
- centos7下部署mysql主从复制
首先大致看一下这个图 环境说明: 系统:centos7 IP:master:192.168.7.235 slave:192.168.7.226 mysql版本MySQL-5.7 1.Master 下载 ...
- docker: read tcp 192.168.7.235:36512->54.230.212.9:443: read: connection reset by peer.
在学习rancher的时候去下载rancher/agent镜像的时候,出现报错:docker: read tcp 192.168.7.235:36512->54.230.212.9:443: r ...
- 【angular】 ng-click 失效
情况一:ng-click 和ng-if 一起使用 情况二:AngularJS中动态添加的ng-click 失效 正常情况(即非动态插入 DOM 对象)下,ng-click 这样的指令之所以有效(即点击 ...
- Android Wear创建一个通知
创建Android Wear的通知实际上和手机上创建没啥区别,主要是多了几个新类,只要用熟悉了一切都好办了.(如果只是测试通知,则直接运行wear app就能够看到效果) 创建一个简单的wear通知分 ...
- k8s 节点的 NodeAffinity 使用
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2 kind: Deployment metadata: name: vi ...
- UVA10838 The Pawn Chess
UVA好题没人写系列,感觉可以稍稍练习一下面向对象编程的形式(大雾) 题意很简单,在国际象棋的棋盘中有一些兵,走到对方底线即为胜利,问最优决策下谁能获胜.并输出最小步数. 首先这里的棋盘都只有\(4\ ...
- Linux每天一个命令:iostat
iostat用于输出CPU和磁盘I/O相关的统计信息 安装Sysstat工具包 centos: yum install sysstat ubuntu: sudo apt-get install sys ...
- Linux Namespace : Network
Network namespace 在逻辑上是网络堆栈的一个副本,它有自己的路由.防火墙规则和网络设备.默认情况下,子进程继承其父进程的 network namespace.也就是说,如果不显式创建新 ...
- 个人实战演练全过程——No.1 最大连续子数组求和
之前的一次个人总结和一次单元测试入门学习是开启软件工程课程的前奏曲,也是热身,现在大家对于这门课程也有了初步的了解和认识,这次要开始真正的演奏了,要从头到尾完全靠自己的能力来解决一个问题,进行实战演练 ...
- Python全栈开发之路 【第一篇】:Python 介绍
本节内容 一.Python介绍 python的创始人为荷兰人——吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本 ...