一、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的扩容机制的更多相关文章

  1. 关于ArrayList的扩容机制

    关于ArrayList的扩容机制 ArrayList作为List接口常用的一个实现类,其底层数据接口由数组实现,可以保证O(1) 复杂度的随机查找, 在增删效率上不如LinkedList,但是在查询效 ...

  2. 浅谈 ArrayList 及其扩容机制

    浅谈ArrayList ArrayList类又称动态数组,同时实现了Collection和List接口,其内部数据结构由数组实现,因此可对容器内元素实现快速随机访问.但因为ArrayList中插入或删 ...

  3. 【数组】- ArrayList自动扩容机制

    不同的JDK版本的扩容机制可能有差异 实验环境:JDK1.8 扩容机制: 当向ArrayList中添加元素的时候,ArrayList如果要满足新元素的存储超过ArrayList存储新元素前的存储能力, ...

  4. Java ArrayList自动扩容机制

    动态扩容 1.add(E e)方法中 ①  ensureCapacityInternal(size+1),确保内部容量,size是添加前数组内元素的数量 ②  elementData[size++] ...

  5. ArrayList动态扩容机制

    初始化:有三种方式 1.默认的构造器,将会以默认的大小来初始化内部的数组:public ArrayList(); 2.用一个ICollection对象来构造,并将该集合的元素添加到ArrayList: ...

  6. 学习ArrayList的扩容机制

    基于jdk8 1.首先我们看new ArrayList中 public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDA ...

  7. 小白也能看懂的ArrayList的扩容机制

    来,话不多说进入正题!我们下面用最简单的代码创建ArrayList并添加11个元素,并 一 一 讲解底层源码:在说之前,给大家先普及一些小知识: >ArrayList底层是用数组来实现的 > ...

  8. 送分题,ArrayList 的扩容机制了解吗?

    1. ArrayList 了解过吗?它是啥?有啥用? 众所周知,Java 集合框架拥有两大接口 Collection 和 Map,其中,Collection 麾下三生子 List.Set 和 Queu ...

  9. ArrayList源码解析(二)自动扩容机制与add操作

    本篇主要分析ArrayList的自动扩容机制,add和remove的相关方法. 作为一个list,add和remove操作自然是必须的. 前面说过,ArrayList底层是使用Object数组实现的. ...

随机推荐

  1. 游览器发送http请求经过的步骤

    OSI参考模型(Open System Interconnection,开放系统互连),全称为开放系统互联参考模型 ,OSI将计算机网络体系结构划分为了七层 TCP/IP协议族(TCP/IP Prot ...

  2. 分布式锁(一) Zookeeper分布式锁

    什么是Zookeeper? Zookeeper(业界简称zk)是一种提供配置管理.分布式协同以及命名的中心化服务,这些提供的功能都是分布式系统中非常底层且必不可少的基本功能,但是如果自己实现这些功能而 ...

  3. SpringBoot实战之SpringBoot自动配置原理

    SpringBoot 自动配置主要通过 @EnableAutoConfiguration, @Conditional, @EnableConfigurationProperties 或者 @Confi ...

  4. iptables 从一台机到另一台机端口转发

    启用网卡转发功能#echo 1 > /proc/sys/net/ipv4/ip_forward 举例:从192.168.0.132:21521(新端口)访问192.168.0.211:1521端 ...

  5. WiFi-ESP8266入门http(3-2)网页认证上网-post请求

    测试账号密码 加密模式  1 18011210338  + 015871     - 测试2 1601120382       +1 mimaHENFuzb  -1 打开网页 手机端 http://1 ...

  6. windows系统VS2017编译boost

    1. 下载boost, 解压,进入boost源目录 2. 打开vs2017 x86 CMD工具,输入bootstrap.bat,等待初始化完毕 x86编译 bjam stage --toolset=m ...

  7. 还是要习惯在linux环境下作Java开发

    要FQ 怎么在ubuntu上安装jdk 网址: https://www.youtube.com/watch?v=NZB3Iy7Lve4 需要网站:http://p.web.umkc.edu/pv6xc ...

  8. for或者while的标记循环

    for或者while的标记循环 今天在写代码的时候,发现一个for循环前有一个字母,不知道这个是什么语法,后来查了一下,这个语法是用来实现标记循环的功能 这个是代码块 r:for(int rowNum ...

  9. 完成了Coursera的一个机器学习课程

    终于完成了这个课程,从开始学习,到现在差不多过了一年的时间,中间由于一些原因耽搁了,最终还是完成了,记录一下!

  10. C#邮件发送类 简单实用 可自定义发件人名称

    上图看效果 MailHelper: public class MailHelper { public bool SendMail(MailSender sender,out string errorM ...