ArrayList初始化

问题:执行以下代码后,这个list的列表大小(size)和容量(capacity)分别是多大?

List<String> list = new ArrayList<>();

答案是:size = 0, capacity = 0,即我们使用无参构造方法创建ArrayList对象时,大小和容量都是为0。

那么如果我继续执行:

        for(int i=0;i<100;i++) {
list.add(String.valueOf(i));
}

每次add之后,size和capacity 分别是多少?

答案是:

size = 1, capacity = 10
size = 2, capacity = 10
size = 3, capacity = 10
size = 4, capacity = 10
size = 5, capacity = 10
size = 6, capacity = 10
size = 7, capacity = 10
size = 8, capacity = 10
size = 9, capacity = 10
size = 10, capacity = 10
size = 11, capacity = 15
size = 12, capacity = 15
size = 13, capacity = 15
size = 14, capacity = 15
size = 15, capacity = 15
size = 16, capacity = 22
size = 17, capacity = 22
size = 18, capacity = 22
size = 19, capacity = 22
size = 20, capacity = 22
size = 21, capacity = 22
size = 22, capacity = 22
size = 23, capacity = 33
size = 24, capacity = 33
size = 25, capacity = 33
size = 26, capacity = 33
size = 27, capacity = 33
size = 28, capacity = 33
size = 29, capacity = 33
size = 30, capacity = 33
size = 31, capacity = 33
size = 32, capacity = 33
size = 33, capacity = 33
size = 34, capacity = 49
size = 35, capacity = 49
size = 36, capacity = 49
size = 37, capacity = 49
size = 38, capacity = 49
size = 39, capacity = 49
size = 40, capacity = 49
size = 41, capacity = 49
size = 42, capacity = 49
size = 43, capacity = 49
size = 44, capacity = 49
size = 45, capacity = 49
size = 46, capacity = 49
size = 47, capacity = 49
size = 48, capacity = 49
size = 49, capacity = 49
size = 50, capacity = 73
size = 51, capacity = 73
size = 52, capacity = 73
size = 53, capacity = 73
size = 54, capacity = 73
size = 55, capacity = 73
size = 56, capacity = 73
size = 57, capacity = 73
size = 58, capacity = 73
size = 59, capacity = 73
size = 60, capacity = 73
size = 61, capacity = 73
size = 62, capacity = 73
size = 63, capacity = 73
size = 64, capacity = 73
size = 65, capacity = 73
size = 66, capacity = 73
size = 67, capacity = 73
size = 68, capacity = 73
size = 69, capacity = 73
size = 70, capacity = 73
size = 71, capacity = 73
size = 72, capacity = 73
size = 73, capacity = 73
size = 74, capacity = 109
size = 75, capacity = 109
size = 76, capacity = 109
size = 77, capacity = 109
size = 78, capacity = 109
size = 79, capacity = 109
size = 80, capacity = 109
size = 81, capacity = 109
size = 82, capacity = 109
size = 83, capacity = 109
size = 84, capacity = 109
size = 85, capacity = 109
size = 86, capacity = 109
size = 87, capacity = 109
size = 88, capacity = 109
size = 89, capacity = 109
size = 90, capacity = 109
size = 91, capacity = 109
size = 92, capacity = 109
size = 93, capacity = 109
size = 94, capacity = 109
size = 95, capacity = 109
size = 96, capacity = 109
size = 97, capacity = 109
size = 98, capacity = 109
size = 99, capacity = 109
size = 100, capacity = 109

从中看出了规律:

即:ArrayList无参初始化是,容量是0,往list里面添加一个元素,容量开始扩容,扩容大小是10,当我的size到达10之后,再继续添加时,容量是拿当前的容量乘以1.5倍,舍去小数取整,即为新容量大小。

那如果继续无限添加元素呢,答案是:

拿最后一次扩容的容量与 整型最大值 - 8比较,如果是大于的话,取整型最大值(即:2^31 -1),如果是小于,则取整型最大值 - 8

ArrayList扩容源码如下:

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

capacity 是list的私有属性,也没有提供相关的方法获取这个值,不过我们可以通过反射来获取这个值:

    public int getArrayListCapacity(List arrayList) {
Class<ArrayList> arrayListClass = ArrayList.class;
int capacity = 0;
try { Field field = arrayListClass.getDeclaredField("elementData"); //获取 elementData 字段
field.setAccessible(true);// 设置为可访问
Object[] objects = (Object[])field.get(arrayList);
//返回当前ArrayList实例的容量值
capacity = objects.length;
} catch (Exception e) {
e.printStackTrace();
capacity = -1;
}
return capacity;
}

测试代码:

        List<String> list = new ArrayList<>();
System.out.println(getArrayListCapacity(list));
for(int i=0;i<100;i++) {
list.add(String.valueOf(i));
System.out.println("size = " + list.size() + ", capacity = " + getArrayListCapacity(list));
}

ArrayList扩容机制实探的更多相关文章

  1. ArrayList扩容机制

    一.先从 ArrayList 的构造函数说起 ArrayList有三种方式来初始化,构造方法源码如下: 1 /** 2 * 默认初始容量大小 3 */ 4 private static final i ...

  2. ArrayList扩容机制以及底层实现

    简介 来源:博客园    作者:吾王彦 博客链接:https://www.cnblogs.com/qinjunlin/p/13724987.html ArrayList动态数组,是 java 中比较常 ...

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

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

  4. ArrayList的扩容机制

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

  5. 浅谈JAVA中HashMap、ArrayList、StringBuilder等的扩容机制

    JAVA中的部分需要扩容的内容总结如下:第一部分: HashMap<String, String> hmap=new HashMap<>(); HashSet<Strin ...

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

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

  7. 关于ArrayList的扩容机制

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

  8. Java ArrayList自动扩容机制

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

  9. 浅谈 ArrayList 及其扩容机制

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

随机推荐

  1. Xshell远程连接Linux系统

    一般来说我们连接Linux,会使用到一些远程连接工具 比如:Xshell和Xftp Xshell:远程连接linux系统 Xftp:远程在Linux系统中上传或下载文件 Xshell和Xftp百度云链 ...

  2. 蒲公英 · JELLY技术周刊 Vol.03

    蒲公英 · JELLY技术周刊 Vol.03 「蒲公英」期刊全新升级--JELLY技术周刊!深度挖掘业界热点动态,来自团队大咖的专业点评,带你深入了解团队研究的技术方向. 登高远眺 天高地迥,觉宇宙之 ...

  3. Python爬虫入门(基础实战)—— 模拟登录知乎

    模拟登录知乎 这几天在研究模拟登录, 以知乎 - 与世界分享你的知识.经验和见解为例.实现过程遇到不少疑问,借鉴了知乎xchaoinfo的代码,万分感激! 知乎登录分为邮箱登录和手机登录两种方式,通过 ...

  4. Asp.Net Core 3.1 的启动过程5

    前言 本文主要讲的是Asp.Net Core的启动过程,帮助大家掌握应用程序的关键配置点. 1.创建项目 1.1.用Visual Studio 2019 创建WebApi项目. 这里面可以看到有两个关 ...

  5. PHPSTORM快捷键On Mac

    Command+Shift+O快捷定位文件,需要输入文件名称 Command+鼠标左键点击方法,快捷转到方法实现 Command+Option+方向左键,快捷返回上一步跳转方法之前 Shift+F6统 ...

  6. ajax后台返回指定的错误码

    js: $.ajax({ type: "POST", url: 'post.php', data: serialNumber + "&getSerialNumbe ...

  7. [Linux] 检查是否已有进程在运行

    出处:sblim-sfcb-1.4.9 / sfcBroker.c int process_is_running() { #define STRBUF_LEN 512 #define BUF_LEN ...

  8. Cannot find or open the PDB file

    打开VS:工具 --> 选项 --> 调试-->符号接下来就是选择Microsoft,然后确认

  9. Prometheus+Grafana 监控 Docker

    cAdvisor (Container Advisor) :用于收集正在运行的容器资源使用和性能信息. https://github.com/google/cadvisor Prometheus(普罗 ...

  10. 27.rm命令

    rm命令可以删除指定的文件或目录.也可以将某个目录及其下属的所有文件及其子目录均删除掉.对于链接文件,只是删除整个链接文件,而原有文件保持不变. 选项:-f:强制删除. -r:递归处理,将指定目录下的 ...