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 配置Redis
application.properties 文件内容 #Redis数据库索引(默认为0) spring.redis.database=0 #Redis服务器地址 spring.redis.host= ...
- ---mipi command
可惜这是5.1系统: http://www.cnblogs.com/lialong1st/p/8534728.html
- Suse linux enterprise 11添加设置中文输入法的方法
Suse中输入法的设置没有在控制中心中,而是在应用程序里默认会安装好的SCIM输入法设置里边添加. 打开SCIM输入法设置->输入法引擎->全局设置,有很多国家的输入法可以选择,想要的找到 ...
- 在Ubuntu上升级SQLite,并让Python使用新版SQLite
(本文适用于Debian系的Linux,如Ubuntu.Raspbian等等.) 在Linux上,Python的sqlite3模块使用系统自带的SQLite引擎,然而系统自带的SQLite可能版本太老 ...
- 【MYSQL】MYSQLの環境構築
ダウンロード:https://dev.mysql.com/downloads/mysql/ 手順① 手順② mysql.iniの設定について [mysql]default-character-set= ...
- 了解一下SQL映射文件
1:SQL映射文件 MyBatis真正强大之处就在于SQL映射语句,相对于强大的功能,SQL映射文件的配置非常简单,与JDBC相比减少了50%的代码.下面是关于SQL映射文件的几个顶级元素配置 map ...
- mysql mycat 中间件安装与使用
一,什么是mycat 一个彻底开源的,面向企业应用开发的大数据库集群 支持事务.ACID.可以替代MySQL的加强版数据库 一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群 一 ...
- java后端学习记录2019
学习计划 2019年计划 1.学习计算机基础,并加以实践.包括LeetCode刷题.数据库原理(索引和锁.Sql优化等).网络协议(Http.Tcp).操作系统(加深Linux).<Http权威 ...
- java第六章异常
异常: 程序运行一旦出现异常程序就会立刻结束不在向下运行 处理异常:在程序执行代码时,万一发生了异常,程序会按照处理的方法对一场进行处理办法,程序将继续执行 try-catch-finally-thr ...
- jquery-confirm使用方法
简要教程 jquery-confirm是一款功能强大的jQuery对话框和确认框插件.它提供多种内置的主题效果,可以实现ajax远程加载内容,提供动画效果和丰富的配置参数等.它的特点还有: 可以使用键 ...