ArrayList增加扩容问题 源码分析
public class ArrayList<E>{
private static final int DEFAULT_CAPACITY = 10;//默认的容量是10
private static final Object[] EMPTY_ELEMENTDATA = {};//长度为空的时候的数组,不可变的
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//默认长度的空数组
transient Object[] elementData; //使用中的临时可变化的数组
private int size;//数组中的个数
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
protected transient int modCount = 0;//
public void ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];//新建一个
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;//默认是0,就把空数组复制给它
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);//参数非法异常
}
}
public void ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;//空参的情况下默认0的数组赋值给它
}
/*增加*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
/*检查是否需要扩容*/
private void ensureCapacityInternal(int minCapacity) {
//如果数组是空数组,最小容量赋值为默认10
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
/*确定扩容的大小
* elementData是用来存储实际内容的数组。minExpand 是最小扩充容量。
* DEFAULTCAPACITY_EMPTY_ELEMENTDATA共享的空数组实例用于默认大小的空实例。
* 根据传入的最小需要容量minCapacity来和数组的容量长度对比,若minCapactity大于或等于数组容量,则需要进行扩容。
*
*
* */
private void ensureExplicitCapacity(int minCapacity) {
modCount++; //AbstractList.class中的值
// 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);//默认的相当于1.5倍?
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;//如果还是不够,就把需要的值赋值
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);//判断newCapacity大容量情况,考虑minCapacity
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
/*大容量处理*/
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError(); //如果minCapacity小于0 ,内存溢出
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE : //如果minCapacity也大于MAX_ARRAY_SIZE
MAX_ARRAY_SIZE; //否则扩容到MAX_ARRAY_SIZE
}
/* 综上所述,ArrayList相当于在没指定initialCapacity时就是会使用延迟分配对象数组空间,
当第一次插入元素时才分配10(默认)个对象空间。假如有20个数据需要添加,那么会分别在第一次的时候,
将ArrayList的容量变为10 ,之后扩容会按照1.5倍增长。也就是当添加第11个数据的时候,
Arraylist继续扩容变为10*1.5=15;当添加第16个数据时,继续扩容变为15 * 1.5 =22个
在JDK1.7中,如果通过无参构造的话,初始数组容量为0,当真正对数组进行添加时,才真正分配容量。
每次按照1.5倍(位运算)的比率通过copeOf的方式扩容。
在JKD1.6中,如果通过无参构造的话,初始数组容量为10.每次通过copeOf的方式扩容后容量为原来的1.5倍加1。
*
*/
}
ArrayList增加扩容问题 源码分析的更多相关文章
- ArrayList实现原理及源码分析之JDK8
转载 ArrayList源码分析 一.ArrayList介绍 Java 集合框架主要包括两种类型的容器: 一种是集合(Collection),存储一个元素集合. 一种是图(Map),存储键/值对映射. ...
- ArrayList相关方法介绍及源码分析
目录 ArrayList简介: ArrayList 相关方法介绍 代码表示 相关方法源码分析 ArrayList简介: java.util.ArrayList 是我们最常用的一个类,ArrayList ...
- ArrayList总结及部分源码分析
ArrayList源码阅读笔记 1. ArrayList继承的抽象类和实现的接口 ArrayList类实现的接口 List接口:里面定义了List集合的基本接口,ArrayList进行了实现 Rand ...
- 4.Java集合-ArrayList实现原理及源码分析
一.ArrayList概述: ArrayList 是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存 ArrayList不是线程安全的,只能用在单线程的情况 ...
- 关于JDK1.8 HashMap扩容部分源码分析
今天回顾hashmap源码的时候发现一个很有意思的地方,那就是jdk1.8在hashmap扩容上面的优化. 首先大家可能都知道,1.8比1.7多出了一个红黑树化的操作,当然在扩容的时候也要对红黑树进行 ...
- java ArrayList 迭代器快速失败源码分析
先来看一个例子: @Test void test2() { ArrayList<String> list = new ArrayList<String>(); list.add ...
- 20220929-ArrayList扩容机制源码分析
示例代码 public class ArrayListSource { public static void main(String[] args) { ArrayList arrayList = n ...
- 大杂烩 -- ArrayList的动态增长 源码分析
基础大杂烩 -- 目录 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 问题:当ArrayList中放入的元素一直增加会如 ...
- ArrayList用法详解与源码分析
说明 此文章分两部分,1.ArrayList用法.2.源码分析.先用法后分析是为了以后忘了查阅起来方便-- ArrayList 基本用法 1.创建ArrayList对象 //创建默认容量的数组列表(默 ...
随机推荐
- springboot性能优化
一.扫描优化 原文链接:http://www.studyshare.cn/blog-front/blog/details/1135 SpringBoot项目中的启动类,会使用@SpringBootAp ...
- 新装 Win7 系统装完驱动精灵,一打开到检测界面就卡死——原因与解决方案
1.现象: 重装系统后,鼠标反应慢,且不能上网.因此装了个驱动精灵,准备更新下驱动,但驱动精灵一打开到检测界面就卡死(换驱动人生.鲁大师也一样). 2.原因: Win7 系统 iso 中自带的驱动程序 ...
- 不学无术的下场——OO第一单元总结
第一单元OO作业总结 第一次作业 第一次作业的要求是对仅有常数和幂函数的式子进行求导. 由于是第一次接触JAVA,对很多东西都还不熟悉,尤其是正则表达式做得不好.当时我的思路如下: 建立Pol ...
- UI设计篇·入门篇·绘制简单自定义矩形图/设置按钮按下弹起颜色变化/设置图形旋转
Android的基本控件和图形有限,难以满足所有的实际需要和设计需求,好在Android给出了相对完善的图形绘制和自定义控件的API,利用这些API,可以基本满足设计的需求. 自定义图像和控件的方法: ...
- Office免费激活方法!亲测有效!2019年4月3日测试
内容转载自:https://blog.csdn.net/qq_41785863/article/details/83619401 防止原博主删除,我先放上自己下载好了的工具分享链接. 链接:https ...
- Java学习--变量
参考 http://www.runoob.com/java/java-variable-types.html java变量使用前 java中的所有变量在使用前必须声明并且初始化 类变量和实例变量会默 ...
- 【400】numpy.pad 为数组加垫(迷宫类题目)
参考:Numpy学习——数组填充np.pad()函数的应用 举例说明: import numpy as np a = np.zeros((3, 4), dtype=int) a array([[0, ...
- springboot的打包方式
先写一个测试接口 package com.example.demo; import org.springframework.web.bind.annotation.RequestMapping; im ...
- 配置ESP8266 NONOS SDK时由于工具链版本差异引发的故障
前几天部署ESP8266_NONOS_SDK时遇到了一个看似奇怪的问题,描述如下: examples例程可以通过编译,但烧写到ESP8266模块后,程序无法正常运行,编译和烧写的相关配置均无误.在bo ...
- idea使用svn or git
有时候项目开始使用svn 后来切换为git, 配置文件还在,导致有时候默认是svn,配置文件在 .idea --> vcs.xml 中, <mapping directory=" ...