ArrayList扩容分析
一段java代码
String e = "q3234v";
List<String> list = new ArrayList<String>();
for (int i = 0; i < 25; i++) {
list.add(e);
}
执行这段代码,list会扩容几次
查看ArrayList的add方法,在添加元素之前会执行ensureCapacityInternal方法
这个时候size为0
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
继续看ensureCapacityInternal方法,DEFAULT_CAPACITY的值为10,此时minCapacity为1
private static final int DEFAULT_CAPACITY = 10;
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
这时候执行:ensureExplicitCapacity
此时minCapacity的值为10,接下来执行扩容方法
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
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:
System.out.println(minCapacity+"------"+newCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
minCapacity的值为10
新空间大小的值为 0+0>>1 = 0
所以第一次扩容完 后新空间大小为10
接下当list.add()执行到第11次的时候
minCapacity=11
newCapacity = 10+10>>1 = 15(1010>>1 = 101= 5)
i执行到16的时候,此时又发现空间不够了
minCapacity=16
newCapacity = 15+15>>1 = 22(1111>>1 = 7)
所以容量到25还需要再执行一次扩容
一共会执行4次扩容
这时候可能会发现在扩容的时候会执行 elementData = Arrays.copyOf(elementData, newCapacity)方法
所以为了减少copyOf的操作
在大概知道List的长度的情况下,在创建的时候应该给一个容量,在容量不够的情况下才会执行扩容操作
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
ArrayList扩容分析的更多相关文章
- ArrayList的分析(转)
一. ArrayList概述: ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存. ArrayList不是线程安全的,只能用在单线程环境 ...
- ArrayList 扩容原理
面试中经常问到的问题之一就是List的扩容机制了,他是怎么做到扩容的,大家都能答出来底层是数组,复制一个数组来扩容,但是再具体一点来说,大家就不知道该怎么说了,如果不看源码说这么多确实就差不多了,但是 ...
- ArrayList扩容机制
一.先从 ArrayList 的构造函数说起 ArrayList有三种方式来初始化,构造方法源码如下: 1 /** 2 * 默认初始容量大小 3 */ 4 private static final i ...
- 都说新的Arraylist 扩容是(1.5倍+1) 看了1.8的源代码发现不是这么回事
都说新的Arraylist 扩容是(1.5倍+1) 看了1.8的源代码发现不是这么回事 就用下面这段代码在jdk的三个版本运行看了下效果 import java.lang.reflect.Field; ...
- 分享知识-快乐自己:都说新的Arraylist 扩容是(1.5倍+1) 看了1.8的源代码发现不是这么回事
都说新的Arraylist 扩容是(1.5倍+1) 看了1.8的源代码发现不是这么回事 就用下面这段代码在jdk的三个版本运行看了下效果: import java.lang.reflect.Field ...
- coding++:都说新的Arraylist 扩容是(1.5倍+1) 看了1.8的源代码发现不是这么回事
都说新的Arraylist 扩容是(1.5倍+1) 看了1.8的源代码发现不是这么回事 就用下面这段代码在jdk的三个版本运行看了下效果: import java.lang.reflect.Fiel ...
- ArrayList扩容机制实探
ArrayList初始化 问题:执行以下代码后,这个list的列表大小(size)和容量(capacity)分别是多大? List<String> list = new ArrayList ...
- external-resizer 源码分析/pvc 扩容分析
kubernetes ceph-csi分析目录导航 基于tag v0.5.0 https://github.com/kubernetes-csi/external-resizer/releases/t ...
- ArrayList原理分析(重点在于扩容)
首先,ArrayList定义只定义类两个私有属性: /** * The array buffer into which the elements of the ArrayList are stored ...
随机推荐
- okHttp3 源码分析
一, 前言 在上一篇博客OkHttp3 使用详解里,我们已经介绍了 OkHttp 发送同步请求和异步请求的基本使用方法. OkHttp 提交网络请求需要经过这样四个步骤: 初始化 OkHttpClie ...
- CentOS修改Mysql字符集
1.mysql>show variables like 'character_set%'; 显示如下: +--------------------------+----------------- ...
- 实验三《敏捷开发与XP实践》_实验报告
实验三<敏捷开发与XP实践>_实验报告 一.实验内容和步骤 提交点1: 任务要求: 实验三 敏捷开发与XP实践 http://www.cnblogs.com/rocedu/p/479577 ...
- k8s简单介绍
k8s是什么? 它是用来解决容器部署,调度,伸缩等基础的功能的软件 k8s的优点? 易学:轻量级,简单,容易理解 便携:支持公有云,私有云,混合云,以及多种云平台 可拓展:模块化,可插拔,支持钩子,可 ...
- Python将函数放入模块
函数可以将通用的代码封装起来,便于其他程序或者方法调用.将函数存放在文件中,这个文件被称为模块.将函数存储在独立的模块中,可与其他程序员共享这些文件而不是整个程序. fun.py def say_hi ...
- 网络配置及一些shell命令概览
一.临时配置网络(ip,网关,dns)+永久配置 1.临时配置网络IP地址命令为“ifconfig 网卡名 ip地址/24”,例如: ifconfig eth0 192.168.16.253/24 2 ...
- js调用后台接口进行下载
js调用后台接口一定不能用ajax location.href=$$pageContextPath +'downfile/down.do?filname='+row.fileUrl;
- Android jni/ndk编程三:native访问java
一.访问静态字段 Java层的field和method,不管它是public,还是package.private和protected,从 JNI都可以访问到,Java面向语言的封装性不见了. 静态字段 ...
- Docker安装ElasticSearch 版本7.1.1
一.Docker 部署 ElasticSearch 1.从仓库中查找所有ElasticSearch的镜像 [root@iZwz99dhxbd6xwly17tb3bZ app]# docker sear ...
- 在oracle中使用基表建立月表的存储过程
某些系统需要按月分表来保存数据.下面的存储过程演示了如何使用基表来建立每个月的月表. 处理思路是: 1:首先,为基表建立好表和对应的索引. 2:将基表保存到一个存储过程需要的表中. ...