ArrayList底层操作机制源码解析

 更新时间:2023年09月19日 10:59:36   作者:风过无痕2018  
这篇文章主要介绍了ArrayList底层操作机制源码解析,当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,第1次添加,则扩容elementData为10,如需要再次扩容,则扩容elementData为1.5倍,需要的朋友可以参考下

ArrayList 的底层操作机制源码

扩容机制:

  • ArrayList中维护了一个0bject类型的数组elementData. transient Object[] elementData; //transient表示瞬间,短暂的,表示该属性不会被序列化
  • 当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,第1次添加,则扩容elementData为10,如需要再次扩容,则扩容elementData为1.5倍。
  • 如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容, 则直接扩容elementData为1.5倍。

debug源码

  • 使用无参构造器,创建和使用ArrayList源码
    /**
     * 创建一个空的elementData数组 = {}
     */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
   /**
	* 执行list.add方法, 先确定是否要扩容,再执行添加操作
	*/
    public boolean add(E e) {
    	// 每次都要看看是否需要扩容
        ensureCapacityInternal(size + 1); //ensureCapacityInternal:确认容量
        elementData[size++] = e;
        return true;
    }
   /**
	* 该方法确定minCapacity , 第一次扩容为10
	*/
   private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { 
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        ensureExplicitCapacity(minCapacity);
    }
   /**
	* modCount:记录当前集合被修改的次数,如果elementData的容量不够,就调用grow方法扩容
	*/
    private void ensureExplicitCapacity(int minCapacity) {
        modCount++; // modCount:记录当前集合被修改的次数,防止多线程操作出现的异常
        if (minCapacity - elementData.length > 0) 
        	// 如果elementData的容量不够,就调用grow方法扩容
            grow(minCapacity);
    }
   /**
	* 真的扩容,使用扩容机制来确定扩容到多大
	* 第一次newCapacity为10, 第二次及其以后按照1.5倍扩容
	* 扩容的是Arrays.copyOf(), 能保留以前的数据
	*/
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        //(oldCapacity >> 1)的意思是oldCapacity / 2
        int newCapacity = oldCapacity + (oldCapacity >> 1); //(1.5倍扩容)
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity; //第一次就是10
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // Arrays.copyOf 将 elementData{} 扩容为newCapacity大小
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

方法一步步返回

  • 使用有参构造器,创建和使用ArrayList源码
   /**
	* 第一次就按照elementData的1.5倍扩容
	* 整个执行的流程和前面的无参构造的一样
	*/
    public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
        	// 创建了一个指定大小的elementData数组 
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }

整个执行的流程和无参构造的一样

到此这篇关于ArrayList底层操作机制源码解析的文章就介绍到这了,更多相关ArrayList源码内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Jmeter参数化实现原理及过程解析

    Jmeter参数化实现原理及过程解析

    这篇文章主要介绍了Jmeter参数化实现原理及过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • Java实现数字转成英文的方法

    Java实现数字转成英文的方法

    这篇文章主要介绍了Java实现数字转成英文的方法,涉及java数组与字符串的相关操作技巧,需要的朋友可以参考下
    2015-05-05
  • JDBC的基本操作与Statement和PreparedStateMent使用区别分析

    JDBC的基本操作与Statement和PreparedStateMent使用区别分析

    这篇文章主要介绍了JDBC的基本操作与Statement和PreparedStateMent使用区别,Java Database Connectivity,它是代表一组独立于任何数据库管理系统(DBMS)的API,声明在java.sql与javax.sql包中,是SUN(现在Oracle)提供的一组接口规范
    2023-04-04
  • Java如何设置过期时间的map的几种方法

    Java如何设置过期时间的map的几种方法

    本文主要介绍了Java如何设置过期时间的map的几种方法,常见的解决方法有:ExpiringMap、LoadingCache及基于HashMap的封装三种,下面就详细的介绍一下,感兴趣的可以了解下
    2022-03-03
  • Spring Boot中使用AOP统一处理web层异常的方法

    Spring Boot中使用AOP统一处理web层异常的方法

    这篇文章主要介绍了Spring Boot中使用AOP统一处理web层异常的相关资料,需要的朋友可以参考下
    2018-03-03
  • springboot 配置DRUID数据源的方法实例分析

    springboot 配置DRUID数据源的方法实例分析

    这篇文章主要介绍了springboot 配置DRUID数据源的方法,结合实例形式分析了springboot 配置阿里DRUID数据源的具体步骤与相关操作技巧,需要的朋友可以参考下
    2019-12-12
  • MyBatis insert标签及常用属性详解

    MyBatis insert标签及常用属性详解

    这篇文章主要介绍了MyBatis insert标签,insert 标签中没有 resultType 属性,只有查询操作才需要对返回结果类型进行相应的指定,需要的朋友可以参考下
    2023-10-10
  • springboot+mybatis配置clickhouse实现插入查询功能

    springboot+mybatis配置clickhouse实现插入查询功能

    这篇文章主要介绍了springboot+mybatis配置clickhouse实现插入查询功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-08-08
  • Java Spring @Autowired的这些骚操作,你都知道吗

    Java Spring @Autowired的这些骚操作,你都知道吗

    这篇文章主要介绍了彻底搞明白Spring中的自动装配和Autowired注解的使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2021-09-09
  • 详解Java synchronized关键字的用法

    详解Java synchronized关键字的用法

    在多线程编程中常常使用锁机制来确保同一时刻只有一个线程能够修改共享内存,在Java中一般是使用synchronized作为锁机制,下面就让我们来学习一下如何使用synchronized实现线程安全吧
    2023-08-08

最新评论