ArrayList无参构造函数为:

public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

而DEFAULTCAPACITY_EMPTY_ELEMENTDATA是一个空数组,即无参ArrayList创建时内部初始容量为0,

当向ArrayList中增加数据时,先检查elementData数组的大小,如果elementData数组已经无法在存放元素,需要进行扩容,具体的扩容方法为grow方法

public boolean add(E e) {
//检查elementData数组是否可以能够存放下一个元素,
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
} private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
//这种情况是无参构造方法创建的ArrayList,增加数据时elementData扩容为DEFAULT_CAPACITY(该值为10)大小的数组,
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
} private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
} private void ensureExplicitCapacity(int minCapacity) {
modCount++; // overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}

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);
}

测试程序如下:

private static void testArrayList() throws Exception {
List<String> list = new ArrayList<>();
Field field = ArrayList.class.getDeclaredField("elementData");
field.setAccessible(true);
for (int i = 0; i < 100; i++) {
Object[] data = (Object[]) field.get(list);
int before = data.length;
list.add(String.valueOf(i));
data = (Object[]) field.get(list);
int after = data.length;
if (before != after) {
System.out.println(String.format("增加第%s个元素时进行了扩容,原来内部数组大小为:%s,扩容后为:%s", i + 1, before, after));
}
}
}

测试结果如下:

增加第1个元素时进行了扩容,原来内部数组大小为:0,扩容后为:10
增加第11个元素时进行了扩容,原来内部数组大小为:10,扩容后为:15
增加第16个元素时进行了扩容,原来内部数组大小为:15,扩容后为:22
增加第23个元素时进行了扩容,原来内部数组大小为:22,扩容后为:33
增加第34个元素时进行了扩容,原来内部数组大小为:33,扩容后为:49
增加第50个元素时进行了扩容,原来内部数组大小为:49,扩容后为:73
增加第74个元素时进行了扩容,原来内部数组大小为:73,扩容后为:109

如果将ArrayList初始容量设置为5,即List<String> list = new ArrayList<>(5);

测试结果如下:

增加第6个元素时进行了扩容,原来内部数组大小为:5,扩容后为:7
增加第8个元素时进行了扩容,原来内部数组大小为:7,扩容后为:10
增加第11个元素时进行了扩容,原来内部数组大小为:10,扩容后为:15
增加第16个元素时进行了扩容,原来内部数组大小为:15,扩容后为:22
增加第23个元素时进行了扩容,原来内部数组大小为:22,扩容后为:33
增加第34个元素时进行了扩容,原来内部数组大小为:33,扩容后为:49
增加第50个元素时进行了扩容,原来内部数组大小为:49,扩容后为:73
增加第74个元素时进行了扩容,原来内部数组大小为:73,扩容后为:109

ArrayList数组扩容方式(基于jdk1.8)的更多相关文章

  1. ArrayList 源码分析 基于jdk1.8:

    1:数据结构: transient Object[] elementData;  //说明内部维护的数据结构是一个Object[] 数组 成员属性: private static final int ...

  2. ArrayList源码解读(jdk1.8)

    概要 上一章,我们学习了Collection的架构.这一章开始,我们对Collection的具体实现类进行讲解:首先,讲解List,而List中ArrayList又最为常用.因此,本章我们讲解Arra ...

  3. Java集合(四)--基于JDK1.8的ArrayList源码解读

    public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess ...

  4. ArrayList的实现细节(基于JDK1.8)

    ArrayList是我们经常用到的一个类,下面总结一下它内部的实现细节和使用时要注意的地方. 基本概念 ArrayList在数据结构的层面上讲,是一个用数组实现的list,从应用层面上讲,就是一个容量 ...

  5. 基于JDK1.8的ArrayList剖析

    前言 本文是基于JDK1.8的ArrayList进行分析的.本文大概从以下几个方面来分析ArrayList这个数据结构 构造方法 add方法 扩容 remove方法 (一)构造方法 /** * Con ...

  6. 日常学习随笔-自定义了一个MyArrayListDefin集合(数组扩容+迭代器+JDK1.8新方法+详细说明)

    一.自定义了一个ArrayList的模拟集合(源码+详细说明) 前段时间分析了下ArrayList集合的源码,总觉得如果不自己定义一个的话,好像缺了点什么,所以有了如下的代码. 代码可以说是逐行注释了 ...

  7. Java集合基于JDK1.8的ArrayList源码分析

    本篇分析ArrayList的源码,在分析之前先跟大家谈一谈数组.数组可能是我们最早接触到的数据结构之一,它是在内存中划分出一块连续的地址空间用来进行元素的存储,由于它直接操作内存,所以数组的性能要比集 ...

  8. ArrayList源码阅读笔记(基于JDk1.8)

    关键常量: private static final int DEFAULT_CAPACITY = 10; 当没有其他参数影响数组大小时的默认数组大小 private static final Obj ...

  9. Java -- 基于JDK1.8的ArrayList源码分析

    1,前言 很久没有写博客了,很想念大家,18年都快过完了,才开始写第一篇,争取后面每周写点,权当是记录,因为最近在看JDK的Collection,而且ArrayList源码这一块也经常被面试官问道,所 ...

随机推荐

  1. 在沙箱中IE不能上网的解决方法

    近期在解决一个问题,在我们的沙箱中IE不能上网 现象:     IE不能上网.输入www.baidu.com 提示:不能查找到DNS.也不能ping 通     其它浏览器上网没有问题(SG浏览器,C ...

  2. @loj - 2092@ 「ZJOI2016」大森林

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 小 Y 家里有一个大森林,里面有 n 棵树,编号从 1 到 n. ...

  3. ImportError: No module named tensorflow.compat.v1 忽略已经安装的某个包版本 忽略已安装版本

    ImportError: No module named tensorflow.compat.v1 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声 ...

  4. PHP 手机短信验证码 laravel 实现流程

    https://blog.csdn.net/uknow0904/article/details/80336941 本人在自己博客(Laravel)的注册部分 使用手机号注册,需要发送短信验证码. 使用 ...

  5. OpenStack组件系列☞glance简介

    Glance项目提供虚拟机镜像的发现,注册,取得服务. Glance提供restful API可以查询虚拟机镜像的metadata,并且可以获得镜像. 通过Glance,虚拟机镜像可以被存储到多种存储 ...

  6. Android本地数据存储: Reservoir

    一:前言 今天做项目,准备使用本地存储,把一些数据存在本地磁盘上,比如用户名.密码这样的.其实大家都知道,这种情况最常用的就是SharedPreferences了,我也不例外,脑子里第一个想到的就是用 ...

  7. 自然语言处理课程(二):Jieba分词的原理及实例操作

    上节课,我们学习了自然语言处理课程(一):自然语言处理在网文改编市场的应用,了解了相关的基础理论.接下来,我们将要了解一些具体的.可操作的技术方法. 作为小说爱好者的你,是否有设想过通过一些计算机工具 ...

  8. get和post的区别?

    GET:一般用于信息获取,使用URL传递参数,对所发送信息的数量也有限制,一般在2000个字符 POST:一般用于 修改服务器上的资源,对所发送的信息没有限制. GET方式需要使用Request.Qu ...

  9. jq杂项方法/工具方法----isArray()

    https://www.cnblogs.com/sandraryan/ $.isArray()函数用于判断指定参数是否是一个数组.返回布尔值. <!DOCTYPE html> <ht ...

  10. zoj 2338 The Towers of Hanoi Revisited

    The Towers of Hanoi Revisited Time Limit: 5 Seconds Memory Limit: 32768 KB Special Judge You all mus ...