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;

构造方法

// 指定容量创建
public ArrayList(int initialCapacity) {
     if (initialCapacity > 0) {
         // 创建容量为initialCapacity的数组
         this.elementData = new Object[initialCapacity];
     } else if (initialCapacity == 0) {
         // initialCapacity为0时,数组指定为EMPTY_ELEMENTDATA
         this.elementData = EMPTY_ELEMENTDATA;
     } else {
         throw new IllegalArgumentException("Illegal Capacity: "+
                                            initialCapacity);
     }
 }

// 默认操作
public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
// 带原始数据的构造方法
public ArrayList(Collection<? extends E> c) {
    Object[] a = c.toArray(); // 原始数据转成数组
    if ((size = a.length) != 0) {
        if (c.getClass() == ArrayList.class) {
            elementData = a; // 原始容器就是ArrayList,那么直接把elementData设置a
        } else {
            // 原始容器不是ArrayList,那么,就把原容器的数据复制成新数组elementData
            elementData = Arrays.copyOf(a, size, Object[].class);
        }
    } else {
        // 原容器是空,那就设置为EMPTY_ELEMENTDATA
        elementData = EMPTY_ELEMENTDATA;
    }
}

add

public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // 里面会对modCount次数加1
    elementData[size++] = e; // 数组下标后移放入新值
    return true; //返回放入成功
}

private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
// 确保容量是够的
private void ensureExplicitCapacity(int minCapacity) {
    modCount++; // 结构修改次数加1

    // 要求的容量大小超过了原数组的大小,需要扩容
    if (minCapacity - elementData.length > 0)
        grow(minCapacity); //扩容
}
// 计算容器的大小
private static int calculateCapacity(Object[] elementData, int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        // 如果elementData是DEFAULTCAPACITY_EMPTY_ELEMENTDATA,那么从DEFAULT_CAPACITY和minCapacity中取最大值
        return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    // 直接返回minCapacity
    return minCapacity;
}


扩容

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;
    // 新容量比最大值MAX_ARRAY_SIZE大
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity); // 取出所能承受的最大容量
    // 创建newCapacity大小的数组,并把原数组元素复制过去
    elementData = Arrays.copyOf(elementData, newCapacity);
}

private static int hugeCapacity(int minCapacity) {
    if (minCapacity < 0) // overflow
        throw new OutOfMemoryError();
    return (minCapacity > MAX_ARRAY_SIZE) ?
        Integer.MAX_VALUE :
    MAX_ARRAY_SIZE;
}

移除元素

每次移除元素都会对数组进行移动,这个性能其实是比较低的,建议ArrayList少做一些增删的操作

// 按下标移除 
public E remove(int index) {
     rangeCheck(index); //检查index的合法性,不能大于size,否则抛出IndexOutOfBoundsException异常

     modCount++;  // 加1
     E oldValue = elementData(index); // 取出index对应的元素

     int numMoved = size - index - 1; // index后面的元素都要移动
     if (numMoved > 0)
         System.arraycopy(elementData, index+1, elementData, index,
                          numMoved);  // 移动元素
     elementData[--size] = null; // 原最后的位置值置null,方便gc

     return oldValue;  // 返回原值
 }
// 按元素对象移除
public boolean remove(Object o) {
    if (o == null) { // 移除的对象本身为null
        for (int index = 0; index < size; index++)
            // 遍历数组,找到第一个为null的元素下标,直接快速移除,并移动元素
            if (elementData[index] == null) {
                fastRemove(index);
                return true;
            }
    } else {
        // 移除的对象本身不为null
        for (int index = 0; index < size; index++)
            // 遍历数组,找到第一个相同的元素下标,直接快速移除,并移动元素
            if (o.equals(elementData[index])) {
                fastRemove(index);
                return true;
            }
    }
    return false;  //没找到,返回false
}

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
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/148679.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

开源免费的Windows应用程序强力卸载工具Bulk Crap UninstallerV5.7的简单使用

经常遇到Windows平台上安装的一些应用&#xff0c;因为应用自带的安装卸载程序有问题、应用的卸载程序损坏、应用卸载需要密码等原因&#xff0c;导致应用无法卸载、卸载不完整等。本介绍了开源的Windows应用程序强力卸载工具Bulk Crap UninstallerV5.7和安装使用的简单说明。 …

Postman+Newman+Jenkins实现接口测试持续集成

近期在复习Postman的基础知识&#xff0c;在小破站上跟着百里老师系统复习了一遍&#xff0c;也做了一些笔记&#xff0c;希望可以给大家一点点启发。 1.新建一个项目 2.设置自定义工作空间 3.执行windows的批处理命令 4.执行系统的Groovy脚本 5.生成的HTML的报告集成到Jenkin…

互斥量保护资源

一、概念 在多数情况下&#xff0c;互斥型信号量和二值型信号量非常相似&#xff0c;但是从功能上二值型信号量用于同步&#xff0c; 而互斥型信号量用于资源保护。 互斥型信号量和二值型信号量还有一个最大的区别&#xff0c;互斥型信号量可以有效解决优先级反转现 象。 …

在 Rocky 中使用 FreeRDP 远程连接 Windows 机器

前言&#xff1a; 远程控制已成为 IT 人员和企业用户在处理日常任务时不可或缺的工具。无论是进行系统管理、支持远程工作&#xff0c;还是协助解决技术问题&#xff0c;一个可靠且高效的远程桌面工具都是业务连续性的关键。开始我个人使用了todesk&#xff08;也曾鲜想过向日…

瑞吉外卖Day04

1.文件的上传下载 Value("${reggie.path}")private String basePath;/*** 文件上传** param file* return*/PostMapping("/upload")public R<String> upload(MultipartFile file) {log.info("文件上传");//原始文件名String originalFilen…

ssm823基于ssm的心理预约咨询管理系统的设计与实现+vue

ssm823基于ssm的心理预约咨询管理系统的设计与实现vue 交流学习&#xff1a; 更多项目&#xff1a; 全网最全的Java成品项目列表 https://docs.qq.com/doc/DUXdsVlhIdVlsemdX 演示 项目功能演示&#xff1a; ————————————————

C语言每日一题(29)合并两个有序链表

力扣网 21合并两个有序链表 题目描述 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 思路分析 最基本的一种思路就是&#xff0c;遍历两个链表&#xff0c;将对应结点的值进行比较&#xff0c;题目要求是要升序排…

springboot单体项目部署

配置类 检查跨域配置类 检查黑白名单是否有问题&#xff0c;是否需要更改 配置文件 检查端口 查看端口是否为需要搭建的端口 检查数据源 查看数据库是否为线上数据库 配置页面 注意&#xff1a;如果是单体项目的话&#xff0c;前端页面是和后端整合在一起的&#xff0…

测试用例的书写方式以及测试模板大全

一个优秀的测试用例&#xff0c;应该包含以下信息&#xff1a; 1 &#xff09; 软件或项目的名称 2 &#xff09; 软件或项目的版本&#xff08;内部版本号&#xff09; 3 &#xff09; 功能模块名 4 &#xff09; 测试用例的简单描述&#xff0c;即该用例执行的目的或方法…

如何创建标准操作规程(SOP)[+模板]

创建、分发和管理流程文档和逐步说明的能力是确定企业成功的关键因素。许多组织依赖标准操作规程&#xff08;SOP&#xff09;作为基本形式的文档&#xff0c;指导他们的工作流程操作。 然而&#xff0c;SOP不仅仅是操作路线图&#xff1b;它们就像高性能车辆中的先进GPS系统一…

LinkedHashMap源码分析

类结构图 从类图结构可以看出&#xff0c;LinkedHashMap继承自HashMap&#xff0c;里面很多实现都是HashMap的&#xff0c;这篇文章主要写出LinkedHashMap自实现的那部分 Entry LinkedHashMap的每个元素项都是一个Entry类对象&#xff0c;该类继承自HashMap.Node类 static c…

【missing-semester】The shell

文章目录 shell 是什么shell 怎么用执行基本程序 Shell中的路径重定向输入输出管道piperoot用户的使用课后练习参考资料 我的操作环境&#xff1a;Windows11下的WSL2(Ubuntu20.04)&#xff0c;之后的所有操作都是基于这个前提的 shell 是什么 命令行操作语言&#xff0c;文本界…

pycharm安装库失败

项目场景 pycharm安装第三方库 问题描述 python 安装第三方库总是安装失败 原因分析&#xff1a; 提示&#xff1a;这里填写问题的分析&#xff1a; 1.网络 2.网墙 解决方案&#xff1a; 加个镜像 –trusted-host mirrors.aliyun.com

【EI会议征稿】第四届信息化经济发展与管理国际学术会议(IEDM 2024)

第四届信息化经济发展与管理国际学术会议&#xff08;IEDM 2024&#xff09; 2024 4th International Conference on Informatization Economic Development and Management 第四届信息化经济发展与管理国际学术会议&#xff08;IEDM 2024&#xff09;将于2024年2月23-25日在…

C++ opencv基本用法【学习笔记(九)】

这篇博客为修改过后的转载&#xff0c;因为没有转载链接&#xff0c;所以选了原创 文章目录 一、vs code 结合Cmake debug1.1 配置tasks.json1.2 配置launch.json 二、图片、视频、摄像头读取显示2.1 读取图片并显示2.2 读取视频文件并显示2.3 读取摄像头并写入文件 三、图片基…

现货黄金职业交易员怎么使用技术分析?

职业的交易员每天要处理很多不同的信息&#xff0c;其中只一部分是涉及技术指标。在这一部分处理技术分析的时间里&#xff0c;只能再分出少之又少的时间给技术指标。那职业交易员会利用做技术指标做什么呢&#xff1f;下面我们就来讨论一下。 识别行情。技术指标的主要作用就是…

TikTok女性创作者:媒体世界的新领袖

在数字时代&#xff0c;社交媒体已成为媒体和娱乐产业的关键组成部分&#xff0c;而TikTok作为最受欢迎的短视频分享平台之一&#xff0c;为女性创作者提供了一个独特的机会来在媒体世界中崭露头角。 这个平台不仅为女性创作者提供了一个创作和分享自己的声音、观点和创意的空…

(三)什么是Vite——Vite 主体流程(运行npm run dev后发生了什么?)

什么是vite系列目录: &#xff08;一&#xff09;什么是Vite——vite介绍与使用-CSDN博客 &#xff08;二&#xff09;什么是Vite——Vite 和 Webpack 区别&#xff08;冷启动&#xff09;-CSDN博客 &#xff08;三&#xff09;什么是Vite——Vite 主体流程(运行npm run dev…

江西产业链现代化1269行动计划引领新能源建设与职业教育教学改革的深度融合

江西产业链现代化1269行动计划引领新能源建设与职业教育教学改革的深度融合 在全球能源转型的时代背景下&#xff0c;江西省积极应对挑战&#xff0c;提出了产业链现代化1269行动计划。这一计划不仅着眼于推动新能源建设&#xff0c;还将新能源建设与职业教育教学改革紧密结合…

Axure9 基本操作(二)

1. 文本框、文本域 文本框&#xff1a;快速实现提示文字与不同类型文字显示的效果。 2. 下拉列表、列表框 下拉列表&#xff1a;快速实现下拉框及默认显示项的效果。 3. 复选框、单选按钮 4.