千家信息网

如何理解ArrayList源码

发表于:2025-02-23 作者:千家信息网编辑
千家信息网最后更新 2025年02月23日,本篇内容主要讲解"如何理解ArrayList源码",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"如何理解ArrayList源码"吧!ArrayList类图如
千家信息网最后更新 2025年02月23日如何理解ArrayList源码

本篇内容主要讲解"如何理解ArrayList源码",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"如何理解ArrayList源码"吧!

ArrayList类图如下:

ArrayList的底层是由数组实现的,数组的特点是固定大小,而ArrayList实现了动态扩容。

ArrayList部分变量如下,在下面的分析中会用到这些变量。

/**  * 默认容量  */ private static final int DEFAULT_CAPACITY = 10; /**  * 空的对象数组  */ private static final Object[] EMPTY_ELEMENTDATA = {}; /**  * 无参构造器创建的空数组  */ private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; /**  * 存放数据的数组的缓存变量  */ transient Object[] elementData; /**  * 元素数量  */ private int size;

一 初始化ArrayList

初始化ArrayList一般会使用以下两个构造器

1.1 无参构造器

初始化ArrayList的时候如果不指定大小,则会创建一个空数组。

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

1.2 指定数组大小的构造器

创建一个预估大小的数组,指定大小后只是指定了数组初始值的大小,不影响后面扩容,指定的好处就是可以节省内存及时间上的开销。

public ArrayList(int initialCapacity) {     if (initialCapacity > 0) {         this.elementData = new Object[initialCapacity];     } else if (initialCapacity == 0) {         this.elementData = EMPTY_ELEMENTDATA;     } else {         throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);     } }

二 添加元素、动态扩容

ArrayList.add(E e)源码:

public boolean add(E e) {     ensureCapacityInternal(size + 1);  // Increments modCount!!     elementData[size++] = e;     return true; }

add()中elementData[size++] = e很好理解,就是将元素插入第size个位置,然后将size++,我们重点来看看ensureCapacityInternal(size + 1)方法;

private void ensureCapacityInternal(int minCapacity) {     if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {         minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);     }     ensureExplicitCapacity(minCapacity); }

ensureCapacityInternal()方法中判断缓存变量elementData是否为空,也就是判断是否是第一次添加元素,如果是第一次添加元素,则设置初始化大小为默认容量10,否则为传入的参数。这个方法的目的就是获取初始化数组容量。获取到初始化容量后调用ensureExplicitCapacity(minCapacity)方法;

private void ensureExplicitCapacity(int minCapacity) {     modCount++;      // overflow-conscious code     if (minCapacity - elementData.length > 0)         grow(minCapacity); }

ensureExplicitCapacity(minCapacity)方法用来判断是否需要扩容,假如第一次添加元素,minCapacity为10,elementData容量为0,那么就需要去扩容。调用grow(minCapacity)方法。

// 数组的最大容量 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;  private void grow(int minCapacity) {     // overflow-conscious code     int oldCapacity = elementData.length;     // 扩容大小为原来数组长度的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 = Arrays.copyOf(elementData, newCapacity); }

grow(minCapacity)方法对数组进行扩容,扩容大小为原数组的1.5倍,如果计算出的扩容容量比需要的容量小,则扩容大小为需要的容量,如果扩容容量比数组最大容量大,则调用hugeCapacity(minCapacity)方法,将数组扩容为整数的最大长度,然后将elemetData数组指向新扩容的内存空间并将元素复制到新空间。

当需要的集合容量特别大时,扩容1.5倍就会非常消耗空间,因此建议初始化时预估一个容量大小。

三 删除元素

ArrayList提供两种删除元素的方法,可以通过索引和元素进行删除。两种删除大同小异,删除元素后,将后面的元素一次向前移动。

ArrayList.remove(int index)源码:

public E remove(int index) {     rangeCheck(index);      modCount++;     E oldValue = elementData(index);      int numMoved = size - index - 1;     if (numMoved > 0)         System.arraycopy(elementData, index+1, elementData, index,                          numMoved);     elementData[--size] = null; // clear to let GC do its work      return oldValue; }

删除元素时,首先会判断索引是否大于ArrayList的大小,如果索引范围正确,则将索引位置的下一个元素赋值到索引位置,将ArrayList的大小-1,最后返回移除的元素。操作图如下,假如我要移除索引为1的元素:

到此,相信大家对"如何理解ArrayList源码"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

数组 元素 容量 大小 方法 索引 源码 变量 构造器 最大 就是 空间 第一次 长度 位置 内存 内容 动态 缓存 学习 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 科研院所召开网络安全工作会 赣榆区有名的网络技术推荐咨询 浙江联想服务器虚拟化操作 惠普塔式服务器维修保养 电脑方舟v3如何进入服务器 网络安全 2019热点 数据库中调用存储过程 腾讯云服务器不能在手机操作吗 长沙蜻蜓网络技术 如果不用数据库连接池 服务器恶意请求防护 学生网络技术开发哪个正规 政府客户对网络安全服务的需求 网络安全工作完成情况 php连接数据库没反应 数据库就是有关数据结构的知识吗 同一用户数据库设计 网络技术服务起名 可以在服务器上安装的培训系统 数据库按日期查询当天数量 世界互联网的科技成果 河北栾谖网络技术有限公司 冠彩网络安全工程师 年度网络安全防护管理报告 滁州im即时通讯软件开发 表格中如何查找多组数据库 网络技术 培养方案 智营网络技术 百度服务器管理账号怎么写 数据库按日期查询当天数量
0