不同的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. ES6 localStorage 类库

    无意中看到的,记录下. 用到了es6语法.支持在js中写构造函数 class CovLocalDB { constructor (name) { this.LS = null this.name = ...

  2. 基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(上)

    最近接触过几个版本的cocos2dx,决定每个大变动的版本都尝试一下.本实例模仿微信5.0版本中的飞机大战游戏,如图: 一.工具 1.素材:飞机大战的素材(图片.声音等)来自于网络 2.引擎:coco ...

  3. DDD实战成绩管理---用户故事

    本次DDD实践选取我们都熟悉的高校成绩管理作为例子. (一).需求描述 每学期学校教务处老师会进行教学安排,具体就是建立教学班,指定该教学班代课教师,上课学生,然后进行排课(忽略此部分,这是另一个系统 ...

  4. vue Map 渲染DOM

    遍历对象(map),以键值对k:v的形式渲染DOM (1)DOM (2)数据模板

  5. CentOS7.2最小化安装后系统优化

    系统初始化技术的演变 1.sysvinit技术 (1)Linux系统的第一个进程(pid=1)为init: Linux 操作系统的启动首先从 BIOS 开始,接下来进入 boot loader,由 b ...

  6. HTML从入门到放弃

    一.HTML 简介 链接:https://www.cnblogs.com/baishuchao/articles/9179920.html 二.HTML 基础 链接:https://www.cnblo ...

  7. idea下增加scala

    1 idea工具下,下载scala插件 2 idea下新建scala工程 File——New——module 如果按照上图,设置后点击下载,出现下图下载过慢情况下, 这里我选择了等待,大概等了半小时才 ...

  8. SQL Server临时表漫谈

    SQL Server是微软的关系型数据库,对于刚入门的我是一个非常友好的开发工具.可视化界面的安装与操作,非常适合刚入门的我. 其实大家要找这方面的资料,在网上一搜一大堆,这里我就不赘述那些了,基本都 ...

  9. Halcon如何保存仿射变换矩阵

    这里我们通过序列化来实现的,如下图,写到硬盘的HomMat2D_1内容和从硬盘里HomMat2D_2读出的内容一致,源代码在图片下方. Halcon源代码: hom_mat2d_identity (H ...

  10. Paper Reading - Deep Visual-Semantic Alignments for Generating Image Descriptions ( CVPR 2015 )

    Link of the Paper: https://arxiv.org/abs/1412.2306 Main Points: An Alignment Model: Convolutional Ne ...