不同的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自动扩容机制的更多相关文章

  1. Java ArrayList自动扩容机制

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

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

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

  3. 关于ArrayList的扩容机制

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

  4. 浅谈 ArrayList 及其扩容机制

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

  5. ArrayList的扩容机制

    一.ArrayList的扩容机制 1.扩容的计算方式是向右位移,即:newSize = this.size + (this.size>>1).向右位移,只有在当前值为偶数时,才是除以2:奇 ...

  6. HashMap自动扩容机制源码详解

    一.简介 HashMap的源码我们之前解读过,数组加链表,链表过长时裂变为红黑树.自动扩容机制没细说,今天详细看一下 往期回顾: Java1.7的HashMap源码分析-面试必备技能 Java1.8的 ...

  7. ArrayList动态扩容机制

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

  8. ArrayList-源码分析-自动扩容机制

    ArrayList类: public class ArrayList....{ ...... private static final int DEFAULT_CAPACITY = 10; //默认容 ...

  9. 学习ArrayList的扩容机制

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

随机推荐

  1. 一个web应用的诞生(5)--数据表单

    下面把角色分为两种,普通用户和管理员用户,至少对于普通用户来说,直接修改DB是不可取的,要有用户注册的功能,下面就开始进行用户注册的开发. 用户表 首先要想好用户注册的时候需要提供什么信息:用户名.密 ...

  2. 软考之信息安全工程师(包含2016-2018历年真题详解+官方指定教程+VIP视频教程)

    软考-中级信息安全工程师2016-2018历年考试真题以及详细答案,同时含有信息安全工程师官方指定清华版教程.信息安全工程师高清视频教程.持续更新后续年份的资料.请点赞!!请点赞!!!绝对全部货真价实 ...

  3. MySQL数据库--连接

    MySQL数据库的概念: MySQL数据库,包括客户端和服务端.客户端就是操作数据库的终端(命令行.navicat),服务端就是安装有MySQL软件的主机(本机或者服务器),MySQL数据库的端口一般 ...

  4. idea项目 run、debug变灰色的问题

    点击如图所示位置的下来三角按钮,然后选择Edit Configurations,或者点击菜单栏Run>Edit Configurations 2 在运行配置窗口,选择一条springboot的运 ...

  5. CSP201403-3:命令行选项

    引言:CSP(http://www.cspro.org/lead/application/ccf/login.jsp)是由中国计算机学会(CCF)发起的"计算机职业资格认证"考试, ...

  6. $_SERVER的详细参数整理下

    PHP编程中经常需要用到一些服务器的一些资料,特把$_SERVER的详细参数整理下,方便以后使用. $_SERVER['PHP_SELF'] #当前正在执行 脚本的文件名,与 document roo ...

  7. Scrum立会报告+燃尽图(十月二十八日总第十九次)

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2288 项目地址:https://git.coding.net/zhang ...

  8. “我爱淘”第二冲刺阶段Scrum站立会议6

    完成任务: 完成学院分类的点击查看书籍功能,可以点击书的条目查看书的详细信息. 计划任务: 将书的详细信息进行完善,并且可以点击收藏以及已预订等功能. 遇到问题: 分类功能,根据不同学院,自动将数据库 ...

  9. Java中switch可以接收的数据类型

    Java支持的数据类型有五种 他们分别是: byte.char.short.int.enum: 以上是JDK1.6以前的版本. JDK1.7时,又增加了String, public class Tes ...

  10. 基础系列(4)—— C#装箱和拆箱

    一 装箱和拆箱的概念 装箱是将值类型转换为引用类型 : 拆箱是将引用类型转换为值类型 : 值类型:包括原类型(Sbyte.Byte.Short.Ushort.Int.Uint.Long.Ulong.C ...