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增加扩容问题 源码分析的更多相关文章

  1. ArrayList实现原理及源码分析之JDK8

    转载 ArrayList源码分析 一.ArrayList介绍 Java 集合框架主要包括两种类型的容器: 一种是集合(Collection),存储一个元素集合. 一种是图(Map),存储键/值对映射. ...

  2. ArrayList相关方法介绍及源码分析

    目录 ArrayList简介: ArrayList 相关方法介绍 代码表示 相关方法源码分析 ArrayList简介: java.util.ArrayList 是我们最常用的一个类,ArrayList ...

  3. ArrayList总结及部分源码分析

    ArrayList源码阅读笔记 1. ArrayList继承的抽象类和实现的接口 ArrayList类实现的接口 List接口:里面定义了List集合的基本接口,ArrayList进行了实现 Rand ...

  4. 4.Java集合-ArrayList实现原理及源码分析

    一.ArrayList概述: ArrayList 是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存 ArrayList不是线程安全的,只能用在单线程的情况 ...

  5. 关于JDK1.8 HashMap扩容部分源码分析

    今天回顾hashmap源码的时候发现一个很有意思的地方,那就是jdk1.8在hashmap扩容上面的优化. 首先大家可能都知道,1.8比1.7多出了一个红黑树化的操作,当然在扩容的时候也要对红黑树进行 ...

  6. java ArrayList 迭代器快速失败源码分析

    先来看一个例子: @Test void test2() { ArrayList<String> list = new ArrayList<String>(); list.add ...

  7. 20220929-ArrayList扩容机制源码分析

    示例代码 public class ArrayListSource { public static void main(String[] args) { ArrayList arrayList = n ...

  8. 大杂烩 -- ArrayList的动态增长 源码分析

    基础大杂烩 -- 目录 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 问题:当ArrayList中放入的元素一直增加会如 ...

  9. ArrayList用法详解与源码分析

    说明 此文章分两部分,1.ArrayList用法.2.源码分析.先用法后分析是为了以后忘了查阅起来方便-- ArrayList 基本用法 1.创建ArrayList对象 //创建默认容量的数组列表(默 ...

随机推荐

  1. BaseRecycleViewAdapterHelper

    BaseRecycleViewAdapterHelper 官方文档 git说明文档 1.English 2.中文

  2. c++ 使用模板按类型统计stl多维容器中元素的数量

    struct ItemCounter{template<typename T1, typename T2, typename = typename std::enable_if<!std: ...

  3. SVM-sklearn

    目的:1000张数字0-9的手写数字,训练识别手写数字:将其作为32*32的0,1化的数字,随后会将其变为1024列的一个向量 原理:SVM就是把平面的点变为一个空间的点,更好切,核函数就是怎么把他变 ...

  4. CentOS7搭建Zookeeper环境

    Linux下安装JDK 1.检查一下系统中的jdk版本 [root@localhost software]# java -version 显示: openjdk version "1.8.0 ...

  5. 音视频处理概要 markdown

    最近要想办法把录制的音视频进行拼接. 比方说此次录制的视频有三段,通过高清直播编码器录制,录制下的标准为h.264 直接用ffmpeg简单拼接,音频会丢失,所以有了此次解决方案(有可能会繁琐,简单方案 ...

  6. String主要方法

    No 方法名称 类型 描述 1 (字符数组)public String(char[] value) 构造 将字符数组变为字符串(Sring类对象) 2 public String(char[] val ...

  7. Android 获取版本号名称工具类

    package com.example.grenaderose.redthunder.utils; import android.content.Context; import android.con ...

  8. 大数据学习笔记5 - Spark

    Spark是一个基于内存计算的大数据并行计算框架.所以,Spark并不能完全替代Hadoop,主要用于替代Hadoop中的MapReduce计算模型. 在实际应用中,大数据处理无非是以下几个类型: 复 ...

  9. pwnable.kr-leg-witeup

    做过后其实知道,是很简单的一段代码,也很容易看懂,看懂后计算key1.key2.key3之和即可. main 汇编: 嗯,看来keyx的返回值是r0了,详细分析r0值. key1: 在arm状态下,r ...

  10. CSDN网站阅读更多:实现原理

    一 设计案例 现在很多网站都增加了阅读更多功能.以CSDN为例,分析其实现原理. 二 设计原理 1 内容区的初始高度是固定的. 2 背景渐变的操作区,遮盖在内容区上面 3 点击按钮时,解除内容区的高度 ...