ArrayList数组扩容方式(基于jdk1.8)
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)的更多相关文章
- ArrayList 源码分析 基于jdk1.8:
1:数据结构: transient Object[] elementData; //说明内部维护的数据结构是一个Object[] 数组 成员属性: private static final int ...
- ArrayList源码解读(jdk1.8)
概要 上一章,我们学习了Collection的架构.这一章开始,我们对Collection的具体实现类进行讲解:首先,讲解List,而List中ArrayList又最为常用.因此,本章我们讲解Arra ...
- Java集合(四)--基于JDK1.8的ArrayList源码解读
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess ...
- ArrayList的实现细节(基于JDK1.8)
ArrayList是我们经常用到的一个类,下面总结一下它内部的实现细节和使用时要注意的地方. 基本概念 ArrayList在数据结构的层面上讲,是一个用数组实现的list,从应用层面上讲,就是一个容量 ...
- 基于JDK1.8的ArrayList剖析
前言 本文是基于JDK1.8的ArrayList进行分析的.本文大概从以下几个方面来分析ArrayList这个数据结构 构造方法 add方法 扩容 remove方法 (一)构造方法 /** * Con ...
- 日常学习随笔-自定义了一个MyArrayListDefin集合(数组扩容+迭代器+JDK1.8新方法+详细说明)
一.自定义了一个ArrayList的模拟集合(源码+详细说明) 前段时间分析了下ArrayList集合的源码,总觉得如果不自己定义一个的话,好像缺了点什么,所以有了如下的代码. 代码可以说是逐行注释了 ...
- Java集合基于JDK1.8的ArrayList源码分析
本篇分析ArrayList的源码,在分析之前先跟大家谈一谈数组.数组可能是我们最早接触到的数据结构之一,它是在内存中划分出一块连续的地址空间用来进行元素的存储,由于它直接操作内存,所以数组的性能要比集 ...
- ArrayList源码阅读笔记(基于JDk1.8)
关键常量: private static final int DEFAULT_CAPACITY = 10; 当没有其他参数影响数组大小时的默认数组大小 private static final Obj ...
- Java -- 基于JDK1.8的ArrayList源码分析
1,前言 很久没有写博客了,很想念大家,18年都快过完了,才开始写第一篇,争取后面每周写点,权当是记录,因为最近在看JDK的Collection,而且ArrayList源码这一块也经常被面试官问道,所 ...
随机推荐
- Maven command
mvn eclispe:clean mvn eclispe:eclispe mvn clean package mvn clean package -Dmaven.test.skip=true mvn ...
- SGU 101 Domino【欧拉路径】
题目链接: http://acm.sgu.ru/problem.php?contest=0&problem=101 题意: N个多米诺骨牌,每个骨牌左右两侧分别有一个0~6的整数(骨牌可以旋转 ...
- cocos2d-x 特效集合
本文转载自:http://www.cnblogs.com/linux-ios/archive/2013/04/09/3009292.html bool HelloWorld::init() { /// ...
- 自动编码(AE)器的简单实现
一.目录 自动编码(AE)器的简单实现 一.目录 二.自动编码器的发展简述 2.1 自动编码器(Auto-Encoders,AE) 2.2 降噪自编码(Denoising Auto-Encoders, ...
- poj 1039 Pipe (Geometry)
1039 -- Pipe 理解错题意一个晚上._(:з」∠)_ 题意很容易看懂,就是要求你求出从外面射进一根管子的射线,最远可以射到哪里. 正解的做法是,选择上点和下点各一个,然后对于每个折点位置竖直 ...
- Levenshtein distance 编辑距离算法
这几天再看 virtrual-dom,关于两个列表的对比,讲到了 Levenshtein distance 距离,周末抽空做一下总结. Levenshtein Distance 介绍 在信息理论和计算 ...
- 在SuperSocket中启用TLS/SSL传输层加密
关键字: TLS, SSL, 传输层加密, 传输层安全, 证书使用, X509Certificate SuperSocket 支持传输层加密(TLS/SSL) SuperSocket 有自动的对TLS ...
- HDU 2191多重背包问题、
#include<cstdio> #include<cmath> #include<iostream> #include<cstring> +; int ...
- H3C 帧中继显示与调试
- tf.variance_scaling_initializer() tensorflow学习:参数初始化
CNN中最重要的就是参数了,包括W,b. 我们训练CNN的最终目的就是得到最好的参数,使得目标函数取得最小值.参数的初始化也同样重要,因此微调受到很多人的重视,那么tf提供了哪些初始化参数的方法呢,我 ...