ArrayList大家都知道了吧,这是一个动态数组。以java语言来说,数组是定长的,在被创建之后就不能被加长或缩短了,因此,了解它的扩容机制对使用它尤为重要。下面,我们就一起来看看它的扩容机制是怎么实现的吧。

首先我们知道,ArrayList有着三种初始化方式:

1)指定大小初始化public ArrayList(int initialCapacity)

2)传入一个Collection对象初始化,并将对象中的数据添加到ArrayList中public ArrayList(Collection c)

3)默认构造函数初始化public ArrayList()

ArrayList扩容机制发生在add()方法调用的时候,从下面的代码我们可以看出当使用无参构造函数创建ArrayList时,它的默认长度会为0private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

public ArrayList()

{

this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;

}

下面是add()方法的源码:public boolean add(E e)

{

//扩容

ensureCapacityInternal(size + 1); // Increments modCount!!

elementData[size++] = e;

return true;

}

根据以上我们可以看到,ensureCapacityInternal()是用来扩容的,形参为最小扩容量,进入此方法后:private void ensureCapacityInternal(int minCapacity)

{

ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));

}

通过方法calculateCapacity(elementData, minCapacity)来获取:private static int calculateCapacity(Object[] elementData, int minCapacity)

{

//如果传入的是个空数组则最小容量取默认容量与minCapacity之间的最大值

if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)

{

return Math.max(DEFAULT_CAPACITY, minCapacity);

}

return minCapacity;

}

ensureExplicitCapacity方法可以判断是否需要扩容:

private void ensureExplicitCapacity(int minCapacity)

{

modCount++;

// 如果最小需要空间比elementData的内存空间要大,则需要扩容

if (minCapacity - elementData.length > 0)

//扩容 grow(minCapacity);

}

下面是重点来了,ArrayList扩容机制关键方法grow():private void grow(int minCapacity)

{

// 获取到ArrayList中elementData数组的内存空间长度

int oldCapacity = elementData.length;

// 扩容至原来的1.5倍

int newCapacity = oldCapacity + (oldCapacity >> 1);

// 再判断一下新数组的容量够不够,够了就直接使用这个长度创建新数组,

// 不够就将数组长度设置为需要的长度

if (newCapacity - minCapacity

newCapacity = minCapacity;

//若预设值大于默认的最大值检查是否溢出

if (newCapacity - MAX_ARRAY_SIZE > 0)

newCapacity = hugeCapacity(minCapacity);

// 调用Arrays.copyOf方法将elementData数组指向新的内存空间时newCapacity的连续空间

// 并将elementData的数据复制到新的内存空间

elementData = Arrays.copyOf(elementData, newCapacity);

}

因此,我们可以清晰看出ArrayList扩容的本质其实就是计算出新的扩容数组的size后实例化它,并将原有数组内容复制到新数组中去。

以上就是关于ArrayList扩容机制的全部内容了,如果你还想要了解更多有关ArrayList相关的java常见问答知识,就快来关注我们的网站吧。

推荐阅读:

arraylist扩容是创建新数组吗 java_arraylist扩容机制要怎么实现?arraylist怎么扩容...相关推荐

  1. arraylist扩容是创建新数组吗 java_Java集合干货——ArrayList源码分析

    前言 在之前的文章中我们提到过ArrayList,ArrayList可以说是每一个学java的人使用最多最熟练的集合了,但是知其然不知其所以然.关于ArrayList的具体实现,一些基本的都也知道,譬 ...

  2. arraylist扩容是创建新数组吗 java_Java 集合,你肯定也会被问到这些

    文章收录在 GitHub JavaKeeper ,N线互联网开发必备技能兵器谱 作为一位小菜 "一面面试官",面试过程中,我肯定会问 Java 集合的内容,同时作为求职者,也肯定会 ...

  3. arraylist扩容是创建新数组吗 java_Java 基础数据结构分析

    java -version java version "13.0.2" 2020-01-14 Java(TM) SE Runtime Environment (build 13.0 ...

  4. arraylist扩容是创建新数组吗 java_Java编程之数组扩容

    一.背景 数组在实际的系统开发中用的越来越少了,我们只有在阅读某些开源项目时才会看到数组的使用.在Java中,数组与List.Set.Map等集合类相比,后者使用起来方便,但是在基本数据类型处理方面, ...

  5. arraylist扩容是创建新数组吗 java_Java ArrayList扩容问题实例详解

    本文研究的主要是Java ArrayList扩容问题实例详解的相关内容,具体介绍如下. 首先我们需要知道ArrayList里面的实质的其实是一个Object类型的数组,ArrayList的扩容问题其实 ...

  6. python创建数组并运行_python-Cython中从现有数组和变量创建新数组...

    与"普通" Python相比,Cython为我们提供了更多对array.array内部的访问,因此我们可以利用它来加速代码: >对于您的小示例,几乎减少了7倍(消除了大部分开 ...

  7. 由已有数组创建新数组:concat()splice()方法

    //concat()方法var a = [ "1", "2", "3", "4", "5" ];va ...

  8. 扩容是元素还是数组_Map扩容源码

    首先我们运行一段代码: 此时运行,程序正常,接下来我们将注释放开: 此时运行发现,OOM了: 为什么new出来HashMap的时候并没有报OOM,而是在第一次进行put操作的时候才报的OOM?我们来看 ...

  9. 扩容是元素还是数组_Java中对数组的操作

    数组对于每一门编程语言来说都是重要的数据结构之一,当然不同语言对于数组的实现及处理也不尽相同. Java语言中提供的数组是用来存储固定大小的同类型元素.如:声明一个数组变量,numbers[100]来 ...

最新文章

  1. 扶梯正确使用_乘坐自动扶梯解释CSS浮动
  2. 洛谷P4768 [NOI2018]归程(Kruskal重构树)
  3. The Art of Unix Programming
  4. halcon模板匹配干扰边缘消除办法(最硬核方式)
  5. 安卓学习 intent
  6. OC中description、 SEL、类本质、self和super用法
  7. SQL Server cast() 批量更新列内容
  8. Python中“if __name__=='__main__':”理解与总结
  9. php中的Register Globals
  10. 《软件调试》第二版正式发售,看雪给你早鸟价
  11. 算法笔记_面试题_16. 二叉树相关_模板及示例十几道
  12. SVN下载项目到本地
  13. vue 定位所在地_Vue 获取当前地理位置
  14. 测试自行车速度的软件,自行车速度测试
  15. Spring Boot (Vue3+ElementPlus+Axios+MyBatisPlus +Spring Boot 前后端分离)
  16. oracle数据库学习笔记(二)(创建表、DDL、DML、单行插入数据、多行插入数据)
  17. 为什么会出现锟斤拷?
  18. EasyFlash 里的 EF_WRITE_GRAN
  19. Introdution(前言)
  20. 2.2 数据库应用系统开发方法

热门文章

  1. 坚持自主创新,凌波微步完成数千万A轮融资,加速半导体产业
  2. 亚马逊独霸美国安云计算未来十年订单;英伟达推出首个元宇宙平台;华为云、天翼云会合并吗?...
  3. 英特尔助力完善AI人才培养,携手微软共促地球可持续发展
  4. 赠书 | 读懂 x86 架构 CPU 虚拟化,看这文就够了
  5. 996!007!同是敲了2万行代码,为什么他却晋升了?
  6. ftl转PDF服务器上中文不显示,解决Linux中swftools转换中文pdf时出现乱码问题
  7. b2b优势与劣势_在Amazon Business平台销售的优点和缺点,B2B卖家清楚吗?
  8. docker 查看实时日志
  9. vue-cli-service不是内部或外部命令,也不是可运行的程序
  10. Jmeter常用插件——梯度加压、响应时间、TPS_老版本