ArrayList扩容代码分析

ArrayList扩容机制是在面试中频繁出现的问题,平时了解的比较含糊,特此记录!

注意:每次发生扩容,其容量扩充为原来的1.5倍 左右

add方法

public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!

    elementData[size++] = e;
    return true;
}
private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
    // 是否为刚初始化后的空数组
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {
    // modCount为此列表被结构修改的次数。
    // 结构修改是指改变列表的大小,或者以某种方式扰乱列表,从而导致正在进行的迭代可能产生不正确的结果。
    // 该字段由迭代器和listIterator方法返回的迭代器和列表迭代器实现使用。如果该字段的值意外更改,迭代器(或列表迭代器)将抛出ConcurrentModificationException异常,以响应next、remove、previous、set或add操作。
    // 这提供了fail-fast行为(一种错误检测机制,一旦检测到可能发生错误,就立马抛出异常,程序不继续往下执行),而不是在迭代期间面对并发修改时的非确定性行为。
    modCount++;

    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

扩容方法

private void grow(int minCapacity) {
    int oldCapacity = elementData.length;
    // 这里使用的是右移计算,比整除高效(注:对于偶数是除2,对于奇数是除2向下取整,所以不完全是1.5倍)
    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中的数据复制出newCapacity个,没有的用null填充
    elementData = Arrays.copyOf(elementData, newCapacity);
}

主要常量及成员变量

// 默认容量
private static final int DEFAULT_CAPACITY = 10;

// 用于空实例的空数组。
private static final Object[] EMPTY_ELEMENTDATA = {};

// 默认大小的空实例。我们将它与EMPTY_ELEMENTDATA区分开来,以了解添加第一个元素时要膨胀多少。
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

// 集合中的元素存储在其中。当ArrayList中的elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA,并且在其添加第一个元素时,容量将被扩展为DEFAULT_CAPACITY。
transient Object[] elementData;

无参构造

public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

Original: https://www.cnblogs.com/daydreamer-fs/p/16711980.html
Author: fogey
Title: ArrayList扩容代码分析

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/615519/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Seata源码分析——RPC模块底层实现

    前言 总览 AbstractNettyRemotingClient——一个RPC请求方法 RpcMessage——RPC协议 编码&解码 Server端Netty初始化 S…

    Java 2023年6月9日
    0111
  • Java之异常

    Java 异常类层次结构图概览 : Exception 和 Error 有什么区别? 在 Java 中,所有的异常都有一个共同的祖先 java.lang 包中的 Throwable…

    Java 2023年6月7日
    091
  • Spring Cloud 新一代Web框架微服务翘楚(一)

    序言 springcloud是微服务架构的集大成者,将一系列优秀的组件进行了整合。基于springboot构建,对我们熟悉spring的程序员来说,上手比较容易。 通过一些简单的注…

    Java 2023年5月30日
    067
  • SpringMvc(三)- CRUD

    1、springMvc的form表单 1.1 标签 1.2 标签 使用springMvc的form表单,快速开发表单及数据自动回显; 原理:在 数据模型中添加一个 参数名为 com…

    Java 2023年6月15日
    078
  • 2020年10月23日笔记

    Java8特性待更新 在公司项目里面有很多这类代码,熟练使用后能够加快开发速度。1、快速便利map的方法map进行快速遍历的方法map.forEach((key,value)-&g…

    Java 2023年6月13日
    068
  • 【K8S】K8S入门基础知识

    一、K8S基础知识 K8S是什么 K8S(Kubernetes)是⼀个容器集群管理系统,可以做容器集群的⾃动化部署,⾃动化扩缩容,维护等功能 为什么要用K8S 传统应⽤部署是通过将…

    Java 2023年6月8日
    092
  • sharding-jdbc教程 看这一篇就够了

    ​ Sharding-JDBC是ShardingSphere的第一个产品,也是ShardingSphere的前身。 它定位为轻量级Java框架,在Java的JDBC层提供的额外服务…

    Java 2023年6月7日
    086
  • 软件工程 统一建模语言(Unified Modeling Language UML) 第4篇随笔

    是一种可视化的语言 规约系统的制品 构造系统的制品 建立系统制品的文档 UML应用范围 可用于对象方法和构件方法 可用于所有应用领域和不同的平台 1.面向对象方法术语/符号 主要有…

    Java 2023年6月16日
    083
  • 使用Intellij IDEA搭建Ext JsMVC web项目

    由于自己从android开发转来学习web开发,最近在学习Jsp,之前接触过一点Extjs,所以用jsp来配合ext试试。 Ext JS介绍 extjs是一个javascript框…

    Java 2023年6月13日
    059
  • elasticsearch 7.7.0 最新版+Java High Level REST Client测试

    服务端:elasticsearch 7.7.0 Docker部署 客户端:spring boot +thymeleaf+Java High Level REST Client 7….

    Java 2023年5月29日
    092
  • 【转】消息中间件MQ的学习境界和路线

    原文:https://www.cnblogs.com/xiexj/p/16095395.html Original: https://www.cnblogs.com/tc310/p…

    Java 2023年5月29日
    095
  • Java-SpringBoot实现AOP (@Around)

    AOP基本总结 连接点(JoinPoint): 连接点是程序运行的某个阶段点,如方法调用、异常抛出等 切入点(Pointcut): 切入点是JoinPoint的集合 是程序中需要注…

    Java 2023年6月8日
    089
  • Java虚拟机启动过程解析

    当我们在编写Java应用的时候,很少会注意Java程序是如何被运行的,如何被操作系统管理和调度的。带着好奇心,探索一下Java虚拟机启动过程。 从 Java&#x6E90;…

    Java 2023年6月6日
    0117
  • 【Redis】WRONGTYPE Operation against a key holding the wrong kind of value

    此异常的出现情况之一:第一次为 key 设置 value 值是字符串类型,第二次 为 相同 key 设置 value 值的类型不同。 posted @2022-09-28 20:5…

    Java 2023年6月15日
    080
  • 关于在网上突然多了一个“孙子”这件事,我是服气的!

    你好呀,我是歪歪。 今天又带大家用新姿势来带吃个的瓜,这瓜老好吃了。 老规矩,先把瓜吃干净,再解锁新的技术姿势。 事情是这样的,上周五的时候不是中国第三艘航空母舰福建舰下水了嘛。 …

    Java 2023年6月5日
    0104
  • java反射与注解

    我们都知道,计算机运行代码,需要经过编译-运行这两个步骤,而反射就是当程序运行状态时,通过类名,就知道这个类有什么属性,有什么方法在里面.简而言之,在 Java 中,只要给定类的名…

    Java 2023年6月8日
    048
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球