ArrayList扩容机制源码分析

ArrayList扩容机制源码分析ArrayList 扩容源码分析

一、ArrayList概述

  • ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长。
  • 实现了Serializable接口,因此它支持序列化,能够通过序列化传输;
  • 实现了RandomAccess接口,支持快速随机访问,实际上就是通过下标序号进行快速访问;
  • 实现了Cloneable接口,能被克隆。

二、ArrayList初始化源码分析

  • 首先有三种方式来初始化:
    • public ArrayList();默认的构造器,将会以默认的大小来初始化内部的数组
      • JDK1.6之前默认大小为10
      • JDK1.6及之后默认大小为0,即一个空数组
    • public ArrayList(Collection
      c)
      用一个ICollection对象来构造,并将该集合的元素添加到ArrayList
    • public ArrayList(int initialCapacity)用指定的大小来初始化内部的数组
======================JDK1.6及以后的无参构造器====================== / * Constructs an empty list with an initial capacity of ten. */ public ArrayList() { 
    // DEFAULTCAPACITY_EMPTY_ELEMENTDATA是空数组 this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = { 
   }; ======================JDK1.6以前的无参构造器====================== public ArrayList() { 
    this(10); } public ArrayList(int initialCapacity) { 
    super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; } 

三、扩容前的容量判断源码分析

add()方法

我们以无参数构造为例,初始化时,数组长度为0.那我现在要添加数据了,数组的长度是怎么变化的?

public boolean add(E e) { 
    ensureCapacityInternal(size + 1); // ①Increments modCount!! elementData[size++] = e; // ② return true; } 
  • ① ensureCapacityInternal方法名的英文大致是“确保内部容量”,size表示的是执行添加之前的元素个数,并非ArrayList的容量,容量应该是数组elementData的长度。ensureCapacityInternal该方法通过将现有的元素个数数组的容量比较。看如果需要扩容,则扩容。
  • 是将要添加的元素放置到相应的数组中。

ensureCapacityInternal()确保容量方法

  • 1.判断实际存储数组是否为空数组,如果是,那么最小容量取默认值10,如果不是则取当前的传参最小容量【即上一步的size + 1】
  • 2.如果minCapacity【需要的长度】超过了当前数组的长度【现有的长度】,则触发扩容
// ① 是如何判断和扩容的。 private void ensureCapacityInternal(int minCapacity) { 
    //如果实际存储数组 是空数组,则最小需要容量就是默认容量 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { 
    minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); } private void ensureExplicitCapacity(int minCapacity) { 
    modCount++; //如果数组(elementData)的长度小于最小需要的容量(minCapacity)就扩容 if (minCapacity - elementData.length > 0) grow(minCapacity); } / * Default initial capacity. */ private static final int DEFAULT_CAPACITY = 10; 

四、扩容机制源码分析

  • 扩容机制:
    • 扩容1.5倍,在JDK1.7及以后采用的是位运算,因为更快!!!!!!
    • int newCapacity = oldCapacity + (oldCapacity >> 1); // 等价于1.5倍扩容
/* *增加容量,以确保它至少能容纳 *由最小容量参数指定的元素数。 * @param mincapacity所需的最小容量 */ private void grow(int minCapacity) { 
    // overflow-conscious code int oldCapacity = elementData.length; //>>位运算,右移动一位。 整体相当于newCapacity =oldCapacity + 0.5 * oldCapacity  // jdk1.7采用位运算比以前的计算方式更快 // 相当于是扩容1.5倍!!!!!!!!!!!!! int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; //jdk1.7这里增加了对元素个数的最大个数判断,jdk1.7以前是没有最大值判断的,MAX_ARRAY_SIZE 为int最大值减去8(不清楚为什么用这个值做比较) if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // 最重要的复制元素方法 elementData = Arrays.copyOf(elementData, newCapacity); } 

五、总结

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/226274.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午11:56
下一篇 2026年3月16日 下午11:56


相关推荐

  • fstream中文路径

    fstream中文路径在C++的标准库中,std::fstream是个挺好用的文件读写流,操作文件很方便,因为是C++标准库,所以没有其它的环境依赖。在使用fstream过程中,有个打开中文路径文件会失败的问题,自己的代码中一直没处理好,这几天终于有点闲心,把这里改透。涉及很多知识点,也是个遗留已久的问题,特此做个记录。在最后用了个一劳永逸的解决此问题方法:将fstream、FILE再包装下。中文路径使用fstream调试程序过程中,发现打开含中文路径的文件时,会打开失败。查了一些资料,说在VS2008、vs200..

    2025年7月11日
    4
  • python错误–‘list‘ object is not callable可能的原因之一

    python错误–‘list‘ object is not callable可能的原因之一第一 代码 功能说明 用正则表达式匹配数字并对数字进行 1 操作 然后替换原数字 str literalbooks 1000 defadd1 match val match group num int val 1returnstr num info re sub r d add1 str printinfosta

    2026年3月19日
    2
  • js中如何遍历对象属性

    js中如何遍历对象属性对象声明 1 varobj 字面量 建议这种方式 方便初始化赋值 2 varobj newObject 对象赋值 1 obj name zhangsan obj age 20 2 obj name zhangsan obj age 20 建议这种方式 访问对象属性值 1 obj name nbsp nbsp 2 obj

    2026年3月26日
    2
  • vuecli3配置webpack_vuecli webpack配置

    vuecli3配置webpack_vuecli webpack配置前言如果我们想在webpack中使用vue,就需要在webpack中配置vue配置vue首先,我们需要在项目中安装vue,安装命令如下:npminstallvue–save安装完成后

    2022年7月30日
    17
  • 递归数列求极限的方法证明_归纳法证明数列极限

    递归数列求极限的方法证明_归纳法证明数列极限高等数学是理工科考研都需要考的科目之一,不管是数一、数二、数三都是考纲中的内容。而极限又是高数中的基础,是微分学的基础。所以,我们一定要打好基础,才能在考试中拿到高分。冷月总结了递归数列极限的求法和证明,希望能够帮助到各位小伙伴。本文为李正元数一全书为参考。

    2025年10月31日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号