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 ...
随机推荐
- iOS8-Sampler
https://github.com/shu223/iOS8-Sampler iOS8-Sampler Code examples for the new functions of iOS 8. Ho ...
- mysql字符串函数:FIND_IN_SET()使用方法详解
语法: FIND_IN_SET(str,strlist) 第一个参数str是要查找的字符串. 第二个参数strlist是要搜索的逗号分隔的字符串列表. 假如字符串str 在由N 子链组成的字符串列表s ...
- 自然语言20.1 WordNet介绍和使用
https://study.163.com/provider/400000000398149/index.htm?share=2&shareId=400000000398149(欢迎关注博主 ...
- python3 http.server 本地服务支持跨域
创建start.py,代码如下: #!/usr/bin/env python try: # Python 3 from http.server import HTTPServer, SimpleHTT ...
- LC 644. Maximum Average Subarray II 【lock,hard】
Given an array consisting of n integers, find the contiguous subarray whose length is greater than o ...
- Redis集群配置和常见异常解决
前文 Redis的Cluster集群,是在分布式且开源环境下最佳的高可用解决方案,可以有效的解决服务器宕机下或高并发下,数据的完整性. 文档前提 Redis 3.0版本或更高版本.(3.0版本开始支持 ...
- Docker,用任何工具链和任何语言来构建任何应用
在看过Docker的两个Hello World的程序后,我们对Docker有了一个大概的感性的认识,那么Docker是到底是什么呢?Docker是一个面向开发者和系统管理员编译,装载,和运行分布式应用 ...
- 由STL map调用clear后,内存不返还给操作系统的问题出发,探讨glibc malloc/free行为(转)
1. 问题 我们的程序有几十个线程,每个线程拥有一个std::map,每个线程都要向自己的std::map中插入大量的数据,但每个数据只有几十字节:当使用完std::map,调用map.clear() ...
- spring_quartz的实现
一.在spring配置文件中引用对应的定时任务配置文件 二.定义定时任务的业务代码 三.配置定时任务配置文件spring-quartz.xml <?xml version="1.0&q ...
- IPTV系统的VOD与TV业务性能测试
IPTV的未来发展正在成为业界的焦点话题.据市场研究公司MRG的统计,全球IPTV用户将由2004年的200万增加至2010年的2000万,预计全球IPTV市场2005-2010年的复合增长率为102 ...