Java集合框架之ArrayList解析

目录

一、ArrayList概述

二、优缺点分析

三、底层数据结构

四、源码分析ArrayList初始化容量

五、源码分析ArrayList扩容策略

六、ArrayList集合源码分析

1. 属性分析

2. 构造方法分析

无参构造方法

指定初始容量的构造方法

传入集合的构造方法

3. 添加元素

add(E e) 方法

add(int index, E element) 方法

4. 修改元素

set(int index, E element) 方法

5. 插入元素

6. 删除元素

remove(int index) 方法

remove(Object o) 方法

七、Vector

1. 底层结构与线程安全

2. 初始容量与扩容策略

3. 为何逐渐被弃用?


一、ArrayList概述

ArrayList 是Java集合框架中最常用的类之一,基于动态数组实现,继承自 AbstractList 并实现了 List 接口。它提供了高效的元素访问能力,适合频繁查询少随机增删的场景。本文将从源码层面深入分析其设计原理、性能特点及最佳实践。

二、优缺点分析

优点:

高效随机访问:通过下标直接访问元素,底层是数组,因此根据下标查找元素的时间复杂度是O(1)。因此检索效率高。

list.get(3); // 直接访问索引3处的元素

尾部操作高效:在数组末尾添加或删除元素时,时间复杂度为 O(1)(无需移动元素)。

缺点:

随机增删效率低:在数组中间插入或删除元素时,需移动后续元素,时间复杂度为 O(n)。不过只要数组的容量还没满,对末尾元素进行增删,效率不受影响

list.add(2, "Java"); // 插入到索引2,后续元素后移

内存浪费:数组容量可能大于实际元素数量,占用额外内存

三、底层数据结构

ArrayList 的核心是一个 Object[] elementData 数组,所有元素按插入顺序依次存储。数组的连续内存特性使得其支持通过下标快速访问元素(时间复杂度 O(1))。

// JDK 11源码片段
public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
    transient Object[] elementData; // 存储元素的数组
    private int size;              // 实际元素个数
}

四、源码分析ArrayList初始化容量

在 Java 中,ArrayList 类有多个构造方法,不同构造方法对初始容量的处理不同:

  • 无参构造方法:初始容量为 0,当第一次调用 add 方法时,容量会被初始化为 10。
  • 带初始容量参数的构造方法:使用指定的初始容量。
  • 带集合参数的构造方法:初始容量为传入集合的大小。

下面是 ArrayList 无参构造方法的源码:

/**
 * Constructs an empty list with an initial capacity of ten.
 */
public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

其中 DEFAULTCAPACITY_EMPTY_ELEMENTDATA 是一个空数组:

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

无参构造:创建一个空数组(初始容量为0),首次调用 add() 方法时扩容至 10

List<String> list = new ArrayList<>(); // elementData = {}
list.add("A"); // 首次扩容,容量变为10

当第一次调用 add 方法时,会触发扩容逻辑,将容量初始化为 10,相关源码如下:

private int newCapacity(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity <= 0) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return minCapacity;
    }
    return (newCapacity - MAX_ARRAY_SIZE <= 0)
        ? newCapacity
        : hugeCapacity(minCapacity);
}

其中 DEFAULT_CAPACITY 的值为 10:

private static final int DEFAULT_CAPACITY = 10;

五、源码分析ArrayList扩容策略

  • 触发条件:当元素数量 size 超过数组长度 elementData.length

  • 扩容规则:新容量为原容量的 1.5倍(通过位运算优化:newCapacity = oldCapacity + (oldCapacity >> 1))。

  • 扩容实现:调用 Arrays.copyOf() 创建新数组并拷贝原数据。

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

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

相关文章

pytorch cnn 实现猫狗分类

文章目录 [toc] 1. 导入必要的库2. 定义数据集类3. 数据预处理和加载4. 定义 CNN 模型5. 定义损失函数和优化器6. 训练模型7. 保存模型8. 使用模型进行预测9 完整代码10. 总结 1. 导入必要的库 import torch import torch.nn as nn import torch.optim as optim from torch.ut…

linux学习【7】Sourc Insight 4.0设置+操作

目录 1.Source Insight是什么&#xff1f;2.需要哪些配置&#xff1f;3.怎么新建项目4.一些问题的解决1.中文乱码问题 按照这个设置就可以了&#xff0c;下面的设置会标明设置理由。 1.Source Insight是什么&#xff1f; 阅读源码&#xff0c;编辑源码&#xff0c;不能编译&am…

有序分数,递归stern-Brocot Tree

题目&#xff1a; 1360. 有序分数 题目 提交记录 讨论 题解 视频讲解 给定一个整数 NN&#xff0c;请你求出所有分母小于或等于 NN&#xff0c;大小在 [0,1][0,1] 范围内的最简分数&#xff0c;并按从小到大顺序依次输出。 例如&#xff0c;当 N5N5 时&#xff0c;所…

一批起飞猪名单配图

好久没有使用风口猪选股指标了&#xff0c;今天去玩了一把&#xff0c;发现起飞猪指标显示了好多一批猪票 华曙高科 汉威科技 双林股份 曼恩斯特 长盈精密 江苏雷利 双飞集团 奥飞数据 硅宝科技 水晶光电 长盈精密

跳表(Skip List)详解

一、什么是跳表&#xff1f; 跳表是一种基于有序链表的高效数据结构&#xff0c;通过建立多级索引实现快速查询。它在平均情况下支持O(log n)时间复杂度的搜索、插入和删除操作&#xff0c;性能接近平衡树&#xff0c;但实现更为简单。 二、核心原理 1. 层级结构 底层为完整…

Pycharm中查找与替换

1、Edit -> Find -> Find 在当前文件中查找 2、Edit -> Find -> Find in Files 在所有文件中查找 3、Edit -> Find -> Replace 在当前文件中执行替换 4、Edit -> Find -> Replace in Files 在所有文件中执行替换

Ollama本地部署大模型(Mac M1 )

本文主要记录第一次尝试使用本地部署开源大模型。 目录 环境准备 安装Ollama 安装open-webUI Docker方式安装open-webUI 第一步&#xff1a;安装docker 第二步&#xff1a;安装open-webUI Anaconda方式安装open-webUI 第一步&#xff1a;安装Anaconda 第二步&#x…

3分钟了解内外网文件传输:常见方法、注意事项有哪些?

内外网文件传输不仅是企业日常运营的基础设施&#xff0c;更是支持业务增长、创新和合规的关键工具。通过高效、安全的文件传输&#xff0c;企业能够更好地应对全球化协作、远程办公和数据安全等挑战&#xff0c;从而在竞争激烈的市场中保持领先地位。 一、内外网文件传输的常…

利用AFE+MCU构建电池管理系统(BMS)

前言 实际BMS项目中&#xff0c;可能会综合考虑成本、可拓展、通信交互等&#xff0c;用AFE&#xff08;模拟前端&#xff09;MCU&#xff08;微控制器&#xff09;实现BMS&#xff08;电池管理系统&#xff09;。 希望看到这篇博客的朋友能指出错误或提供改进建议。 有纰漏…

unity学习49:寻路网格链接 offMeshLinks, 以及传送门效果

目录 1 网格链接 offMeshLinks 功能入口 1.1 unity 2022之前 1.2 unity 2022之后 2 网格链接 offMeshLinks 功能设置 3 点击 offMeshLinks 功能里的bake 3.1 unity 2022之前 3.2 unity 2022之后 3.3 实测link 3.4 跳跃距离增大&#xff0c;可以实现轻功类的效果 4 …

HarmonyOS NEXT网络状态监听HTTP和RCP请求网络

当我们在HarmonyOS NEXT中开发的应用&#xff0c;基本上都会使用网络请求&#xff0c;从服务端获取数据在客户端显示或者供用户交互&#xff0c;有时候网络发生变化时&#xff0c;我们需要做一些相应的操作&#xff0c;接下来我们一起来了解下在HarmonyOS NEXT下如何监听网络状…

如何在 VS Code 中快速使用 Copilot 来辅助开发

在日常开发中&#xff0c;编写代码往往是最耗时的环节之一。而 GitHub Copilot&#xff0c;作为一款 AI 编码助手&#xff0c;可以帮助开发者 自动补全代码、生成代码片段&#xff0c;甚至直接编写完整的函数&#xff0c;大幅提升编码效率。那么&#xff0c;如何在 VS Code 中快…

【16届蓝桥杯寒假刷题营】第2期DAY1I

4.有向无环的路径数 - 蓝桥云课 问题描述 给定 N 个节点 M 条边的有向无环图&#xff0c;请你求解有多少条 1 到 N 的路径。 由于答案可能很大&#xff0c;你只需要输出答案对 998244353 取模后的结果。 输入格式 第一行包含 2 个正整数 N,M&#xff0c;表示有向无环图的节…

伯克利 CS61A 课堂笔记 10 —— Trees

本系列为加州伯克利大学著名 Python 基础课程 CS61A 的课堂笔记整理&#xff0c;全英文内容&#xff0c;文末附词汇解释。 目录 01 Trees 树 Ⅰ Tree Abstraction Ⅱ Implementing the Tree Abstraction 02 Tree Processing 建树过程 Ⅰ Fibonacci tree Ⅱ Tree Process…

Spring Boot 定时任务:轻松实现任务自动化

在现代应用开发中&#xff0c;定时任务是一个常见的需求。比如&#xff0c;我们可能需要定时清理过期数据、定时发送邮件通知等。 操作流程 开启定时任务注解 在启动类添加注解EnableScheduling 设置时间&#xff08;固定时间间隔&#xff09; 使用 Scheduled 注解创建定时…

通过监督微调提升多语言大语言模型性能

引言 澳鹏助力一家全球科技公司提升其大语言模型&#xff08;LLM&#xff09;的性能。通过提供结构化的人工反馈形式的大语言模型训练数据&#xff0c;让该模型在30多种语言、70多种方言中的表现得到优化。众包人员们进行多轮对话&#xff0c;并依据回复的相关性、连贯性、准确…

Flask实现高效日志记录模块

目录 一. 简介&#xff1a; 1. 为什么需要请求日志 二. 日志模块组成 1. 对应日志表创建&#xff08;包含日志记录的关键字段&#xff09; 2. 编写日志记录静态方法 3. 在Flask中捕获请求日志 4. 捕获异常并记录错误日志 5. 编写日志接口数据展示 6. 写入数据展…

【学习笔记】Cadence电子设计全流程(一)Cadence 生态及相关概念

【学习笔记】Cadence电子设计全流程&#xff08;一&#xff09;Cadence 生态及相关概念 1.1 Cadence 生态系统及各模块关系1.2 Cadence相较于Altium Designer在硬件设计中的优势 1.1 Cadence 生态系统及各模块关系 Cadence 提供了一套完整的电子设计自动化 (EDA) 工具链&#…

【Linux Redis】关于用docker拉取Redis后,让虚拟机运行起来redis,并使得其可以连接到虚拟机外的navicat。

步骤一&#xff1a;拉取Redis镜像 docker pull redis 这个命令会下载最新版本的Redis镜像到你的本地Docker仓库中。你也可以指定一个具体的版本号&#xff0c;例如docker pull redis:6.2.6&#xff0c;来拉取特定版本的Redis镜像。 如果拉取遇到问题请参考【Linux AnolisOS】关…

蓝桥与力扣刷题(蓝桥 裁纸刀)

本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 题目&#xff1a;小蓝有一个裁纸刀&#xff0c;每次可以将一张纸沿一条直线裁成两半。 小蓝用一张纸打印出两行三列共 6 个二维码&#xff0c;至少使用九次裁出来&#xff0c…