当前位置: 首页 > article >正文

Java数据结构——ArrayList

Java中ArrayList

  • 一 ArrayList的简介
  • 二 ArrayList的构造方法
  • 三 ArrayList常用方法
    • 1.add()方法
    • 2.remove()方法
    • 3.get()和set()方法
    • 4.index()方法
    • 5.subList截取方法
  • 四 ArrayList的遍历
    • for循环遍历
    • 增强for循环(for each)
    • 迭代器遍历
  • ArrayList问题及其思考

前言
ArrayList是一种 顺序表,⽤⼀段 物理地址连续的存储单元依次存储数据的线性结构,一般情况都是采用数组存储,在数组上实现一些增删查改等等功能, ArrayList是Java中最常用的 动态数组实现之一,其内部的内存空间是可以改变的,今天就来探究一下ArrayList使用及其原理

在这里插入图片描述

一 ArrayList的简介

ArrayList虽然是一个普通的类,但是它实现了List接口

List接口在JDK17的部分源码
在这里插入图片描述
ArrayList类在JDK17的部分源码
在这里插入图片描述
我们可以从上面看出

1. List是一个接口,继承了Collection2. ArrayList是一个类,继承了AbstractList3. ArrayList实现了List中的RandomAccess接口,说明其支持随机访问
4. 实现了Cloneable接口,说明其支持clone
5. 实现了Serializable接口,说明其支持序列化 

下面是ArrayList的一些常用方法,因为其实现了List接口,所以List中的抽象方法,在ArrayList都有
在这里插入图片描述

二 ArrayList的构造方法

ArrayList ()无参构造
ArrayList (int initialCapacity)确定初始容量
ArrayList (Collection<? extends E> c)利用其他Collection来构造
public class Test {public static void main(String[] args) {//1.无参构造List<Integer> list = new ArrayList<>();//2.含参构造,确定其初始化的容量,确定其初始化容量为1List<Integer> list1 = new ArrayList<>(1);//3.利用其他构造//这里list2与list的元素一致List<Integer> list2 = new ArrayList<>(list);}
}

无参构造源码
在这里插入图片描述
在这里插入图片描述
虽然无参构造没有给定容量,但是编译器会默认一个容量,JDK17中默认容量为10

含初始容量一个参数的构造
在这里插入图片描述
如果给定初始容量,编译器会进行判断,如果初始容量>0就按照你给定的容量创建对象,如果初始容量==0就按照默认的容量进行创建,反之如果<0就抛出容量不合法的异常

注意在创建线性表的时候,要指定是什么类型的线性表
1.如果不写类型,编译器会报错,因为其不知道是什么类型
在这里插入图片描述
2.并且其必须是包装类型
如果写成普通类型编译器也会报错
在这里插入图片描述
3.那何为包装类型呢

基本数据类型包装类
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean

这些类型中除了int和char的包装类有所改变,其他的都是基本类型的首字母大写

三 ArrayList常用方法

方法解释
boolean add(E e)尾插 e
void add(int index, E e)将 e插入到 index 位置
boolean addAll(Collection<? extends E> c)尾插 c 中的全部元素
E remove(int index)删除 index 下标元素
boolean remove(Object o)删除遇到的第一个 o
E get(int index)获取下标 index 下标元素
E set(int index, E e)将下标 index 下标元素设置为 e
void clear()清空列表
boolean contains(Object o)判断 o 是否在线性表中
int indexOf(Object o)返回第一个 o 所在下标
int lastIndexOf(Object o)返回最后一个 o 的下标
List subList(int fromIndex, int toIndex)截取部分 list
int size()返回此列表中的实际的元素数

1.add()方法

boolean add(E e)
将指定的元素追加到此列表的末尾。

public class Test {public static void main(String[] args) {List<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);System.out.println(list);}
}

运行结果如下
在这里插入图片描述

注意这里的如果已经确定了是那种包装类型,就不可以在添加其他的包装类型的数据了
在这里插入图片描述

public class Test {public static void main(String[] args) {List<Integer> list = new ArrayList<>(3);list.add(1);list.add(2);list.add(3);System.out.println("扩容前长度"+list.size());list.add(4);System.out.println("扩容后长度"+list.size());System.out.println(list);}
}

运行结果如下
在这里插入图片描述
我们发现一个问题就是上面我们初始化容量为3,但是我们添加了4个元素其并没有报错,为什么呢?那是因为其ArrayList类add方法中有扩容操作,但是这里的真实长度变为4
在这里插入图片描述

void add(int index, E e)
在index下标插入e
index>=0&&index<=其列表的长度

public class Test {public static void main(String[] args) {List<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);//在1下标插入99list.add(1,99);// list.add(4,1);System.out.println(list);}
}

我们要注意这里并不是简单替换,而是将某一个下标修改为一个数后,原本的数要往后偏移
偏移的同时其如果存储不下,也会进行扩容

运行结果如下
在这里插入图片描述
注意这里的下标要合法 index下标>=0&&index<=list.size()
这里等于其list的容量也可以,因为这样正好就相当于上面一个参数的add进行尾插
在这里插入图片描述
如果大于list.size()就会出现数组越界异常
这里长度为3,这里index>=0&&index<=3,因此这里出现数组越界异常异常了
在这里插入图片描述

boolean addAll(Collection<? extends E> c)
将指定集合中的所有元素追加到此列表的末尾
这里是可以自己尾插自己的

public class Test {public static void main(String[] args) {List<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);System.out.println("尾插前list"+list);List<Integer> list1 = new ArrayList<>();list1.add(10);list1.add(20);list1.add(30);//将list1尾插到list后面list.addAll(list1);System.out.println("尾插后list"+list);}
}

在这里插入图片描述
这里其实也是可以自己尾插自己的
下面这个自己尾插自己成功了
在这里插入图片描述
注意这里是不可以不同类型的列表进行尾插
一个列表中不可以放两种包装类型一样,尾插不同类型的肯定会报错
在这里插入图片描述

2.remove()方法

E remove(int index)
删除 index 下标元素
index>=0&&index<列表长度

public class Test {public static void main(String[] args) {List<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);//删除1下标的值list.remove(1);System.out.println(list);}
}

这里删除1下标的值,也就是删除这里的2
运行结果如下
在这里插入图片描述

boolean remove(Object o)
删除遇到的第一个 o
在使用的时候要将一个数装箱以后再进行删除

这里直接使用基本类型就是删除的是对应下标的值,而不是自己想要的

在这里插入图片描述
这时候就要进行装箱操作,这样就可以删除对应的值了,删除的就不是下标对应的值了
这里就是删除第一个出现的1元素,而不是下标,所以这里0下标的1被删除了
在这里插入图片描述

void clear()
清空列表

public class Test {public static void main(String[] args) {List<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);//删除1下标的值Integer a = 1;list.remove(a);System.out.println(list);list.clear();System.out.println("清空后"+list);}
}

这里就是将其置为空
在这里插入图片描述

3.get()和set()方法

E get(int index)
获取下标 index 下标元素

E set(int index, E e)
将下标 index 下标元素设置为 e
index>=0&&index<列表长度

public class Test {public static void main(String[] args) {List<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);System.out.println("获取1下标的值:"+list.get(1));list.set(1,999);System.out.println("修改后1下标的值:"+list.get(1));}
}

这里和add方法不同的是,这个是直接修改值,而add是添加值
运行结果如下
在这里插入图片描述

4.index()方法

int indexOf(Object o) 返回第一个 o 所在下标
int lastIndexOf(Object o) 返回最后一个 o 的下标
找不到就返回-1

public class Test {public static void main(String[] args) {List<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);list.add(1);System.out.println("第一个元素1的下标:"+list.indexOf(1));//0//如果没有找到就返回-1System.out.println(list.indexOf(100));//-1System.out.println("最后一个元素1的下标:"+list.lastIndexOf(1));}
}

在这里插入图片描述

5.subList截取方法

List subList(int fromIndex, int toIndex)
截取下标[fromIndex,toIndex]的list

public class Test {public static void main(String[] args) {List<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);list.add(4);list.add(5);List<Integer> list1 = list.subList(1,3);//这里是左闭右开的截取方法System.out.println("截取[1,3)下标的元素:"+list1);}
}

运行结果如下
在这里插入图片描述
其实这里并不是真正的截取
例如:

public class Test {public static void main(String[] args) {List<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);list.add(4);list.add(5);List<Integer> list1 = list.subList(1,3);//这里是左闭右开的截取方法System.out.println("截取[1,3)下标的元素:"+list1);list1.remove(0);//删除list1中的0下标的值也就是2System.out.println("被截取的list: "+ list);}
}

这里删除截取中0下标的2,而原本的list中的2也被删除了
运行结果如下
在这里插入图片描述
可以看出这里我们对截取的内容删除,导致了list中的这部分内容也被删除了
在这里插入图片描述

只是将其一个对象指向截取的部分,只是将其截取部分的地址放入一个新对象中,因此对截取修改也会影响原本的list

四 ArrayList的遍历

for循环遍历

public class Test {public static void main(String[] args) {List<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);list.add(4);list.add(5);for (int i = 0; i < list.size(); i++) {//获取下标对应的值System.out.print(list.get(i)+" ");}}
}

这里的size()获取其列表长度
进行一个一个下标遍历就行
运行结果如下
在这里插入图片描述

增强for循环(for each)

public class Test {public static void main(String[] args) {List<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);list.add(4);list.add(5);//每个元素的类型为Integerfor (Integer integer:list) {System.out.print(integer+" ");}}
}

这里使用for-each遍历,这里列表中元素类型都为Integer,就用一个临时integer来访问和打印
在这里插入图片描述

迭代器遍历

public class Test {public static void main(String[] args) {List<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);list.add(4);list.add(5);//使用迭代器//从前向后遍历Iterator<Integer> it = list.iterator();//获取其开始位置while(it.hasNext()){//不断的往后走System.out.print(it.next()+" ");}System.out.println();//从后向前遍历给定其下标从其最后面开始ListIterator<Integer> it1 = list.listIterator(list.size());while (it1.hasPrevious()){System.out.print(it1.previous()+" ");}System.out.println();}
}

运行结果如下
在这里插入图片描述

ArrayList问题及其思考

1.在其查找数据是非常简单和高效的
2.但是,ArrayList列表在添加或者删除元素的时候,都需要将其后面的数据向前移动,时间复杂度为O(N)
3.在添加数据时候可能会扩容,是1.5倍数扩容,有点浪费空间

因此还需要其他的数据结构来完成添加或者删除元素会更高效一点

相关文章:

Java数据结构——ArrayList

Java中ArrayList 一 ArrayList的简介二 ArrayList的构造方法三 ArrayList常用方法1.add()方法2.remove()方法3.get()和set()方法4.index()方法5.subList截取方法 四 ArrayList的遍历for循环遍历增强for循环(for each)迭代器遍历 ArrayList问题及其思考 前言 ArrayList是一种 顺…...

科学量化AI对品牌产品印象 首个AI印象(AII)指数发布

2025年4月18日&#xff0c;营销传播数据研究领先机构四度传播研究院(SAC)&#xff0c;正式推出了量化AI大模型对产品整体印象的AI印象&#xff0c;简称AII&#xff08;ARTIFICIAL INTELLIGENCE IMPRESSIONS&#xff09;&#xff0c;同时发布了首个“汽车AI印象榜”。为企业和消…...

Python语法系列博客 · 第8期[特殊字符] Lambda函数与高阶函数:函数式编程初体验

上一期小练习解答&#xff08;第7期回顾&#xff09; ✅ 练习1&#xff1a;找出1~100中能被3或5整除的数 result [x for x in range(1, 101) if x % 3 0 or x % 5 0]✅ 练习2&#xff1a;生成字符串长度字典 words ["apple", "banana", "grape…...

FFmpeg 硬核指南:从底层架构到播放器全链路开发实战 基础

目录 1.ffmpeg的基本组成2.播放器的API2.1 复用器阶段2.1.1 分配解复用上下文2.1.2 文件信息操作2.1.3 综合示例 2. 2 编解码部分2.2.1 分配解码器上下文2.2.2编解码操作2.2.3 综合示例 3 ffmpeg 内存模型3.1 基本概念3.2API 1.ffmpeg的基本组成 模块名称功能描述主要用途AVFo…...

大数据建模与评估

文章目录 实战案例:电商用户分群与价值预测核心工具与库总结一、常见数据挖掘模型原理及应用(一)决策树模型(二)随机森林模型(三)支持向量机(SVM)模型(四)K - Means聚类模型(五)K - Nearest Neighbors(KNN)模型二、运用Python机器学习知识实现数据建模与评估(一…...

UE5有些场景的导航生成失败解决方法

如果导航丢失&#xff0c;就在项目设置下将&#xff1a; 即可解决问题&#xff1a; 看了半个小时的导航生成代码发现&#xff0c;NavDataSet这个数组为空&#xff0c;导致异步构建导航失败。 解决 NavDataSet 空 无法生成如下&#xff1a; 当 NavDataSet 为空的化 如果 bAut…...

MCP(Model Context Protocol 模型上下文协议)科普

MCP&#xff08;Model Context Protocol&#xff0c;模型上下文协议&#xff09;是由人工智能公司 Anthropic 于 2024年11月 推出的开放标准协议&#xff0c;旨在为大型语言模型&#xff08;LLM&#xff09;与外部数据源、工具及服务提供标准化连接&#xff0c;从而提升AI在实际…...

健康养生指南

在快节奏的现代生活中&#xff0c;健康养生成为人们关注的焦点。它不仅关乎身体的强健&#xff0c;更是提升生活质量、预防疾病的关键。掌握科学的养生方法&#xff0c;能让我们在岁月流转中始终保持活力。 饮食是健康养生的基础。遵循 “均衡膳食” 原则&#xff0c;每日饮食需…...

Linux系统:进程终止的概念与相关接口函数(_exit,exit,atexit)

本节目标 理解进程终止的概念理解退出状态码的概念以及使用方法掌握_exit与exit函数的用法以及区别atexit函数注册终止时执行的函数相关宏 一、进程终止 进程终止&#xff08;Process Termination&#xff09;是指操作系统结束一个进程的执行&#xff0c;回收其占用的资源&a…...

Linux下 文件的查找、复制、移动和解压缩

1、在/var/log目录下创建一个hehe.log的文件&#xff0c;其文件内容是&#xff1a; myhostname ghl mydomain localdomain relayhost [smtp.qq.com]:587 smtp_use_tls yes smtp_sasl_auth_enable yes smtp_sasl_security_options noanonymous smtp_sasl_tls_security_opt…...

C语言学习之预处理指令

目录 预定义符号 #define的应用 #define定义常量 #define定义宏 带有副作用的宏参数 宏替换的规则 函数和宏定义的区别 #和## #运算符 ##运算符 命名约定 #undef ​编辑 命令行定义 条件编译 头文件包含 头文件被包含的方式 1.本地头文件包含 2.库文件包含 …...

【STM32单片机】#10 USART串口通信

主要参考学习资料&#xff1a; B站江协科技 STM32入门教程-2023版 细致讲解 中文字幕 开发资料下载链接&#xff1a;https://pan.baidu.com/s/1h_UjuQKDX9IpP-U1Effbsw?pwddspb 单片机套装&#xff1a;STM32F103C8T6开发板单片机C6T6核心板 实验板最小系统板套件科协 实验&…...

fastlio用mid360录制的bag包离线建图,提示消息类型错误

我用mid360录制的bag包&#xff0c;激光雷达的数据类型是sensor_msgs::PointCloud2&#xff0c;但是运行fast_lio中的mid360 launch文件&#xff0c;会报错&#xff08;没截图&#xff09;&#xff0c;显示无法从livox_ros_driver2::CustomMsg转换到sensor_msgs::PointCloud2。…...

二级评论列表-Java实现

二级评论列表是很常见的功能&#xff0c;文章记录了新手用Java实现的具体逻辑。 整体实现逻辑是先用2个sql&#xff0c;分别查出两层数据。然后用java在service中实现数据组装&#xff0c;返给前端。这种实现思路好处是SQL简洁&#xff0c;逻辑分明&#xff0c;便于维护。 一…...

IP检测工具“ipjiance”

目录 IP质量检测 应用场景 对网络安全的贡献 对网络管理的帮助 对用户决策的辅助作用 IP质量检测 检测IP的网络提供商&#xff1a;通过ASN&#xff08;自治系统编号&#xff09;识别IP地址所属的网络运营商&#xff0c;例如电信、移动、联通等。 识别网络类型&#xff1…...

mysql的函数(第二期)

九、窗口函数&#xff08;MySQL 8.0&#xff09;​​ 适用于对结果集的子集&#xff08;窗口&#xff09;进行计算&#xff0c;常用于数据分析场景。 ​​ROW_NUMBER()​​ ​​作用​​&#xff1a;为每一行生成唯一的序号。​​示例​​&#xff1a;按分数降序排名 SELECT n…...

Replicate Python client

本文翻译整理自&#xff1a;https://github.com/replicate/replicate-python 文章目录 一、关于 Replicate Python 客户端相关链接资源关键功能特性 二、1.0.0 版本的重大变更三、安装与配置1、系统要求2、安装3、认证配置 四、核心功能1、运行模型2、异步IO支持3、流式输出模型…...

halcon模板匹配(八)alignment_for_ocr_in_semiconductor

目录 一、alignment_for_ocr_in_semiconductor例程目的二、创建训练和查找用于图像对齐三、图像对齐四、在指定区域内查找文本一、alignment_for_ocr_in_semiconductor例程目的 在一个图像中定义两个区域,一个用于图像对齐,在另一个区域内使用文本模板进行匹配。 二、创建训…...

Java读取JSON文件并将其中元素转为JSON对象输出

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Java读取JSON文件并将其中元素转为JSON对象输…...

华为openEuler操作系统全解析:起源、特性与生态对比

华为openEuler操作系统全解析&#xff1a;起源、特性与生态对比 一、起源与发展历程 openEuler&#xff08;欧拉操作系统&#xff09;是华为于2019年开源的Linux发行版&#xff0c;其前身为华为内部研发的服务器操作系统EulerOS。EulerOS自2010年起逐步发展&#xff0c;支持华…...

Elasticsearch使用及常见的问题

Elasticsearch作为一款分布式搜索与分析引擎&#xff0c;其核心优势在于高性能搜索能力&#xff0c;依托倒排索引和分布式架构&#xff0c;可快速处理海量数据及复杂查询&#xff0c;支持实时索引与动态扩容&#xff0c;兼具高可用性和扩展性。其丰富的RESTful API与查询语言降…...

Python基础总结(七)之条件语句

文章目录 条件语句if一、Python中的真假二、条件语句格式2.1 if语句格式2.2 if-else语句2.3 if-elif-else语句 三、if语句嵌套 条件语句if 条件语句其实就是if语句&#xff0c;在讲解if语句之前需要知道Python中对于真假的判断。 一、Python中的真假 在Python中非0的都为真&…...

命令update-alternatives

❯ which pip /home/ying/anaconda3/bin/pipying192 ~ [2]> which pip /usr/bin/pip使用update-alternatives对他们进行管理和切换 快捷方式 和 实际路径不可以相同 所以我这边选择了/usr/local/bin目录作为介质存储快捷方式&#xff0c;另外该快捷方式会自己创建我们只需选…...

deekseak 本地windows 10 部署步骤

有些场景需要本地部署&#xff0c;例如金融、医疗&#xff08;HIPAA&#xff09;、政府&#xff08;GDPR&#xff09;、军工等&#xff0c;需完全控制数据存储和访问权限&#xff0c;避免云端合规风险或者偏远地区、船舶、矿井等无法依赖云服务&#xff0c;关键设施&#xff08…...

MySQL中常用函数的分类及示例

概述 以下是 MySQL 中常用函数的分类及示例&#xff0c;涵盖字符串处理、数值计算、日期操作、条件判断等常见场景&#xff1a; 一、字符串函数 1. CONCAT(str1, str2, ...) 拼接字符串。 SELECT CONCAT(Hello, , World); -- 输出: Hello World2. SUBSTRING(str, start,…...

<sql>、<resultMap>、<where>、<foreach>、<trim>、<set>等标签的作用和用法

目录 一. sql 代码片段标签 二. resultMap 映射结果集标签 三. where 条件标签 四. set 修改标签 五. trim 标签 六. foreach 循环标签 一. sql 代码片段标签 sql 标签是 mybatis 框架中一个非常常用的标签页&#xff0c;特别是当一张表很有多个字段多&#xff0c;或者要…...

企业级HAProxy高可用离线部署实战(附Kubernetes APIServer负载均衡配置)

企业级HAProxy高可用离线部署实战&#xff08;附Kubernetes APIServer负载均衡配置&#xff09; 摘要&#xff1a;本文深入讲解在离线环境下部署HAProxy 3.1.1的全流程&#xff0c;涵盖源码编译、系统服务封装、K8S APIServer四层负载配置等核心环节&#xff0c;并提供生产级高…...

实现Azure Databricks安全地请求企业内部API返回数据

需要编写一个Databricks在Azure云上运行&#xff0c;它需要访问企业内部的API获取JSON格式的数据&#xff0c;企业有网关和防火墙&#xff0c;API有公司的okta身份认证&#xff0c;通过公司的域账号来授权访问&#xff0c;现在需要创建一个专用的域账号&#xff0c;让Databrick…...

kafka认证部署

首先启动 zookeeper /home/kafka/bin/zookeeper-server-start.sh /home/kafka/config/zookeeper.properties 创建SCRAM证书 /home/kafka/bin/kafka-configs.sh --zookeeper localhost:2181 --alter --add-config SCRAM-SHA-256[iterations8192,passwordliebe],SCRAM-SHA-512[p…...

【项目】CherrySudio配置MCP服务器

CherrySudio配置MCP服务器 &#xff08;一&#xff09;Cherry Studio介绍&#xff08;二&#xff09;MCP服务环境搭建&#xff08;1&#xff09;环境准备&#xff08;2&#xff09;依赖组件安装<1> Bun和UV安装 &#xff08;3&#xff09;MCP服务器使用<1> 搜索MCP…...