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源码这一块也经常被面试官问道,所 ...
随机推荐
- postman post 数据格式
postman post 数据的时候,选择raw的tab ,选择json. 然后在下面的提交json数据, {"photoPath":"bbbbbbbbbbbbbb&qu ...
- HLSL效果框架-多光源效果
原文:HLSL效果框架-多光源效果 昨日不可追, 今日尤可为.勤奋,炽诚,不忘初心 手机淘宝二维码 扫描 或者打开连接:程序设计开发 ,掌声鼓励,欢迎光临. 高级着色器语言(HLS ...
- Myeclipse 设置默认注释
windows-->preference-->Java-->Code Style-->Code Templates code-->New Java files ${fil ...
- linux 端口映射设置
iptables -t nat -A PREROUTING -p tcp --dport 新端口 -j REDIRECT --to-ports 旧端口
- behavior planning——14.implement a cost function in C++
n most situations, a single cost function will not be sufficient to produce complex vehicle behavior ...
- 随机线性网络编码的C语言实现,实现可靠传输:原理(1)
线性方程组,大家都不陌生吧.来一组 A11 *X1 + A12 *X2 + A13 *X3 + A14 *X4 =Q1 A21 *X1 + A22 *X2 + A23 *X3 + A24 *X4 =Q ...
- H3C 数据链路层
- codeforces 1230 div2
C 给一个图,并且在边上放上多米诺骨牌,使得每个多米诺骨牌指向的顶点的数字是一致的,并且每种骨牌只能用一种.问最多能够覆盖多少条边. 先生成每一个点指向的数字,然后判断就好了. #include< ...
- HDU 2717 宽搜第一题、
题意:求n到k的最小路径, n有三种变法 n+1,n-1或者2*n: 贴个广搜的模版在这里把.... 总结一下:一般涉及到求最短路的话用宽搜 #include<iostream> #in ...
- Spring Data Jpa 简单使用事务
对于两张表,需要顺序操作,必须全部表均操作成功才可,否则两张表不操作. 例如,现在有device,collectionpoint两张表,向两张表顺序执行insert操作 SQL如下 INSERT IN ...