ArrayList源码解析

ArrayList 源码深度解析 ArrayList 源码深度解析 一、重新认识ArrayList 什么是ArrayList? ArrayList是基于数组实现的List类,封装了一个动态再分配的Object数组,以达到可以动态增长和缩减的索引序列。 长啥样? 如图,是一个长度为6,存储了6个6的数组,下标(index)从0开始,数组(elementData)表示存储的数据本身。 有哪些基本概念? index 表示数组下标;... 阅读详情

原文链接
ArrayList底层使用数组实现,所以随机访问特定位置的元素的速度特别快,时间复杂度为0(1)

transient Object[] elementData; // non-private to simplify nested class access

ArrayList默认分配大小为10的容量

/**
 * Default initial capacity.
 */
private static final int DEFAULT_CAPACITY = 10;

ArrayList可以给定特定索引删除元素,时间复杂度为O(n)

/**
 * Removes the element at the specified position in this list.
 * Shifts any subsequent elements to the left (subtracts one from their
 * indices).
 *
 * @param index the index of the element to be removed
 * @return the element that was removed from the list
 * @throws IndexOutOfBoundsException {@inheritDoc}
 */
public E remove(int index) {
    //检查元素索引的正确性
    rangeCheck(index);

    //当ArrayList被修改时,该变量累加
    modCount++;
    //获取对应索引位置的元素
    E oldValue = elementData(index);

    //计算需要往前移动的元素个数
    int numMoved = size - index - 1;

    //如果删除的不是最后一个元素,则把对应index后面的元素依次往前移动一个位置
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    //移动完成后需要吧数组中的最后一个元素置为空,方便GC回收
    elementData[--size] = null; // clear to let GC do its work

    return oldValue;
}

也可以删除ArrayList中对应的对象,时间复杂度也为O(n)

/**
 * Removes the first occurrence of the specified element from this list,
 * if it is present.  If the list does not contain the element, it is
 * unchanged.  More formally, removes the element with the lowest index
 * <tt>i</tt> such that
 * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>
 * (if such an element exists).  Returns <tt>true</tt> if this list
 * contained the specified element (or equivalently, if this list
 * changed as a result of the call).
 *
 * @param o element to be removed from this list, if present
 * @return <tt>true</tt> if this list contained the specified element
 */
public boolean remove(Object o) {
    //可以看出ArrayList可以存储null值,先判断是否删除null,否则如果当执行equals方法时会抛出空指针异常
    if (o == null) {
        for (int index = 0; index < size; index++)
            //暴力循环获取第一个为null的索引
            if (elementData[index] == null) {
                //快速移除元素,没有进行索引判断,因为该索引是安全的,不会越界
                fastRemove(index);
                //删除成功
                return true;
            }
    } else {
        for (int index = 0; index < size; index++)
            //调用equals方法暴力查找需要移除的元素
            if (o.equals(elementData[index])) {
                fastRemove(index);
                return true;
            }
    }
    return false;
}

fastRemove方法如下,该方法删除元素时跳过了索引检查

/*
 * Private remove method that skips bounds checking and does not
 * return the value removed.
 */
private void fastRemove(int index) {
    modCount++;
    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
}

接下来看看add方法

/**
 * Appends the specified element to the end of this list.
 *
 * @param e element to be appended to this list
 * @return <tt>true</tt> (as specified by {@link Collection#add})
 */
public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}

在指定位置添加元素,时间复杂度为O(n)

/**
 * Inserts the specified element at the specified position in this
 * list. Shifts the element currently at that position (if any) and
 * any subsequent elements to the right (adds one to their indices).
 *
 * @param index index at which the specified element is to be inserted
 * @param element element to be inserted
 * @throws IndexOutOfBoundsException {@inheritDoc}
 */
public void add(int index, E element) {
    //首先检查index的合法性(0<=index<=arrayList.size)
    rangeCheckForAdd(index);

    //扩容处理
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    //指定位置的所有元素依次往后移动一个位置
    System.arraycopy(elementData, index, elementData, index + 1,
                     size - index);
    //插入元素
    elementData[index] = element;
    size++;
}

清空ArrayList,时间复杂度O(n)

/**
 * Removes all of the elements from this list.  The list will
 * be empty after this call returns.
 */
public void clear() {
    //每次修改该变量都会自加操作
    modCount++;

    // clear to let GC do its work
    for (int i = 0; i < size; i++)
        //全部置空,让GC清理内存
        elementData[i] = null;

    //长度变为0
    size = 0;
}

判断是否含某一个元素

public boolean contains(Object o) {
    //获取对应索引进行判断
    return indexOf(o) >= 0;
}
单片机多级菜单的简单实现 单片机多级菜单的简单实现 多级菜单的思路 最近想把stm32上的oled显示屏做的好看一些,于是动手写了写一个多级菜单,思路很简单,每个页面用单独的函数封装好,每个功能也是用单独的函数进行封装,用了3个按键,两个切换键,一个确定键。 首先来看看用啥判断页面的(这偷个懒,希望没人打我) //页面标志位 uint8_t s1 = 0; //主页面功能号 uint8_t s2 = 0; //主次页面判断标志位 uint16_t s3 = 1; //次页面功能号 主页面的显示函数,这是个很枯燥的一 阅读详情

相关推荐

安卓光速虚拟机ADB调试实战:从密钥配置到设备连接

本文详细介绍了在安卓光速虚拟机中进行ADB调试的完整实战流程。核心在于通过密钥配置解决设备未授权问题,并启用网络调试与端口映射,最终实现电脑与虚拟机的稳定连接。文章提供了从原理理解、脚本修改到实战命令和疑难排查的全方位指南,帮助开发者和爱好者高效利用光速虚拟机作为移动测试沙盒。

CAT789的专栏 561

Shell中创建序列和数组(list、array)

这篇文章主要介绍了Shell中创建序列和数组(list、array)的方法, 一、seq方法生成: // seq [OPTION]... LAST // seq [OPTION]... FIRST LAST // seq [OPTION]... FIRST INCREMENT LAST [chengmo@centos5 ~]$ seq 1000 //起始默认是 1,间隔默认也是1 [chengmo@centos5 ~]$ seq 2 1000 //间隔默认是1 [chengmo@centos5 ~]

Golden_Chen的专栏 6231

Synares病毒实战:如何手动清除C盘隐藏的Synaptics.exe(附资源修复脚本)

本文详细介绍了Synares感染型病毒的手动清除方法,该病毒伪装成Synaptics触摸板驱动,感染EXE和XLSX文件。文章提供了从病毒行为分析、母体清除到被感染文件修复的全流程指南,并附有实用的资源修复脚本和防御加固方案,帮助用户彻底清除这一顽固病毒。

lg888的博客 2356

java中ArrayList 、LinkList区别

1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 2.对于随机访问get和set,ArrayList优于LinkedList,因为ArrayList可以随机定位,而LinkedList要移动指针一步一步的移动到节点处。(参考数组与链表来思考) 3.对于新增和删除操作add和remove,LinedList比较占优势,只需要对指针进行修改即可,而Ar...

kanwoerzi 2721

新手也能搞定!用ADS 2023从零设计一个超宽带Wilkinson功分器(附完整版图)

本文详细介绍了如何使用ADS 2023从零开始设计超宽带Wilkinson功分器,涵盖介质板参数设置、微带线计算优化、版图生成验证等关键步骤。通过实例演示和常见问题排查,帮助射频工程新手快速掌握功分器设计技巧,提升设计效率。

weixin_42692935的博客 476

华为OD技术面真题 - Python开发 - 2

汇总华为OD技术面八股Python八股,高频技术真题并提供详细解答。

qq_45776114的博客 910

jmeter中Beanshell调用ArrayList方法的问题

1、beanshell中使用了ArrayList方法时,如果按照常规的写法:  ArrayList &lt;Company&gt; companyList = new ArrayList&lt;Company&gt;(); 这样子是会报错的: Response message: org.apache.jorphan.util.JMeterException: Error invoking b...

jocleyn的博客 5844

一键熄火:在 SAP ABAP 平台停用 OAuth 2.0 Client 的正确姿势

本文是一篇面向SAP ABAP平台运维与开发团队的实战指南,重点讲解了OAuth 2.0客户端的停用操作。文章首先阐述了停用的必要性——当客户端存在泄漏风险或配置错误时,停用能在阻断访问的同时保留配置。随后详细介绍了通过SOAUTH2事务码执行停用的具体步骤,并区分了"停用"、"删除"和"撤销令牌"三个关键概念及其适用场景。 文章提供了两个真实案例:一个是怀疑客户端泄漏后的紧急处置流程,另一个是合规审计期间的冻结与恢复操作。最后总结了一份验证清单,

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 278

linux shell 创建序列数组(list,array)方法

关于linux数组定义,以及生成方法,请看:linux shell 动态生成 数组系列 seq使用技巧 。这里我主要说的是高效生成list 字符串,还有数组方法。   一、seq方法生成: [chengmo@centos5 shell]$ aNumList=$(seq 100); [chengmo@centos5 shell]$ echo $aNumList 1 2 3 4 5 6

grantlee1988的专栏 6074

Modbus RTU/TCP协议栈手写实现:主从站设计、功能码、CRC、异常响应

本文从协议栈架构、帧结构、功能码、CRC校验、异常响应、主从站设计等多个维度,完整阐述了Modbus RTU/TCP协议栈的手写实现方案。帧间隔机制是RTU的核心,T3.5超时检测决定了帧边界识别CRC16查表法以512字节ROM换取8倍性能提升,适合嵌入式功能码路由表实现可扩展的代码架构,便于新增功能异常响应机制保障协议健壮性,每个错误都有明确反馈Modbus TCP在RTU基础上增加MBAP头,实现以太网扩展多核RTOS环境下的并发访问与线程安全RS-485总线的电气隔离与浪涌保护。

从事移动开发八年,csdn博客专家,阿里云特邀专家,华为云云享专家,高级网络信息安全工程师,大数据工程师(高级),python技术开发(高级),HarmonyOS 应用开发者高级认证,现在某学校任教。 1万+

示波器核心参数选型指南:带宽、采样率与嵌入式调试实战

示波器是电子工程师进行信号观测与故障诊断的基础仪器,其性能由带宽、采样率、通道数、存储深度、触发系统和探头特性共同决定。带宽定义高频响应边界,需遵循5倍法则以保障数字信号上升沿测量精度;采样率则依据奈奎斯特定理并结合工程冗余(通常≥2.5×带宽)实现可靠时域重建。二者协同影响信号完整性评估能力,尤其在UART、I²C、SPI等嵌入式总线调试中至关重要。高存储深度支持长时捕获与毛刺定位,智能触发与硬件协议解码进一步将波形分析升维至语义级。本文围绕真实嵌入式场景,解析参数间的耦合关系与典型误用陷阱。

weixin_42588877的博客 91

集合详解之ArrayList

今天我们来分析一下List中的ArrayList,平常我们编码的过程中,这个是一个非常常用的集合类型。一、 ArrayList概述:        ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存。       ArrayList不是线程安全的,只能用在单线程环境下,多线程环境下可以考虑用Collections.synchronize

士不可以不弘毅,任重而道远 1302

YOLOv11改进策略【损失函数篇】| 替换激活函数为Mish、PReLU、Hardswish、LeakyReLU、ReLU6

在卷积神经网络中,激活函数通过在神经网络中引入非线性,使网络能够学习和逼近复杂函数,从而处理复杂的模式识别与分类问题。

Limiiiing的博客 2796

【源码篇】ArrayList源码解析

ArrayList是什么?ArrayList 是 Java 中的一个很常用的集合类,它具有有序有索引可重复‘、动态扩容线程不安全等特点。ArrayList 底层是基于数组存储元素的,数组是线性表,所以插入和删除元素的时间复杂度是OnO(n)On,根据索引索取元素的时间复杂度 是O1O(1)O1,所以 ArrayList查询快增删比较慢ArrayList常用操作:略……Java常用集合总结扩容核心算法这里通过>>(算术右移)计算出当前容量的一半扩容流程先由方法获取当前集合所需最小容量。

热爱编程、热爱生活、热爱探索 1721

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

ArrayList源码全面解析

ArrayList 是 java 集合框架中比较常用的数据结构,继承自 AbstractList,实现了 List 接口。底层采用数组来实现。ArrayList 实现了java.io.Serializable接口,这意味着ArrayList支持序列化,能通过序列化去传输。

专注Java后端技术干货、项目源码总结分享,期待您的关注。 1370

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

ArrayList核心原理与源码解析

fastRemove避免重复检查提升性能使用双指针原地操作减少内存分配本地方法实现高效数据移动6.3.3.替换指定位置元素/*** 替换列表中指定位置的元素(时间复杂度O(1))* @param index 要替换的位置索引(0 ≤ index < size)* @param element 要存储的新元素(允许为null)* @return 被替换的旧元素* @throws IndexOutOfBoundsException 如果索引越界(index < 0 || index ≥ size)

cj928963824的博客 1978

Java集合源码解析之ArrayList

1.ArrayList源码解析整体流程图概览。

ByteBlossom 936

ArrayList 源码解析

一、ArrayList的概述 ArrayList 是我们开发中常用的一种数据结构,它的底层是基于数组实现的,是一个动态数组,容量你可以动态 增加,ArrayList实现Serializable 接口,他能支持序列化传输;实现了RandomAccess接口,支持快速随机访问,也就是通过下标可以实现快速访问;实现了Cloneable 接口,意味着可以被克隆。 二、ArrayList 的源码解析 首先看...

技术宝库 259
上一篇: 你真的知道JAVA中抽象类和接口的区别么?
下一篇: 设计模式之单例模式
ishellhub
博客等级 码龄9年 102粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值