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倍数扩容,有点浪费空间

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【信息获取能力】

第一层&#xff1a;表象观察 现象&#xff1a;AI系统&#xff08;如GPT-4&#xff09;可以瞬间调用并整合全球互联网上的公开信息&#xff0c;而人类即使穷尽一生也无法完成同等规模的知识储备。 底层逻辑&#xff1a; 存储与检索效率&#xff1a;人类大脑的记忆容量有限&…

03、GPIO外设(三):标准库代码示例

标准库代码示例 1、点亮LED2、LED闪烁3、LED流水灯4、按键控制LED5、蜂鸣器 本章源代码链接&#xff1a; 链接: link 1、点亮LED 实验要求&#xff1a;点亮LED ①LED.c文件的代码如下: #include "LED.h"/*** LED引脚初始化*//* 定义数组&#xff0c;想要添加引脚…

卷积神经网络(CNN)与VGG16在图像识别中的实验设计与思路

卷积神经网络&#xff08;CNN&#xff09;与VGG16在图像识别中的实验设计与思路 以下从基础原理、VGG16架构解析、实验设计步骤三个层面展开说明&#xff0c;结合代码示例与关键参数设置&#xff0c;帮助理解其应用逻辑。 一、CNN与VGG16的核心差异 基础CNN结构 通常包含33~55个…

java导出word含表格并且带图片

背景 我们需要通过 Java 动态导出 Word 文档&#xff0c;基于预定义的 模板文件&#xff08;如 .docx 格式&#xff09;。模板中包含 表格&#xff0c;程序需要完成以下操作&#xff1a; 替换模板中的文本&#xff08;如占位符 ${设备类型} 等&#xff09;。 替换模板中的图…

Oracle19C低版本一天遭遇两BUG(ORA-04031/ORA-600)

昨天帮朋友看一个系统异常卡顿的案例&#xff0c;在这里分享给大家 环境&#xff1a;Exadata X8M 数据库版本19.11 1.系统报错信息 表象为系统卡顿&#xff0c;页面无法刷出&#xff0c;登陆到主机上看到节点1 系统等待存在大量的 cursor: pin S wait on X等待 查看两个节…

2025年Q1数据安全政策、规范、标准以及报告汇总共92份(附下载)

一、政策演进趋势分析 &#xff08;一&#xff09;国家级政策新动向 数据要素市场建设 数据流通安全治理方案&#xff08;重点解析数据确权与交易规则&#xff09; 公共数据授权运营规范&#xff08;创新性提出分级授权机制&#xff09; 新兴技术安全规范 人工智能安全标准…

ERR_PNPM_DLX_NO_BIN No binaries found in tailwindcss

场景复现&#xff1a; 最近在vue3项目中安装了tailwindcss&#xff0c;但是它默认帮我安装的版本是4XX的&#xff0c;导致我执行 npx tailwindcss init -p报错了。 解决方案&#xff1a; 更改tailwindcss的版本为3 pnpm add -D tailwindcss3再次执行生成tailwindcss的初始…

第 4 篇:Motion 拖拽与手势动画(交互篇)—— 打造直觉化交互体验

Framer Motion 的拖拽与手势系统让实现复杂交互变得异常简单。本文将深入解析核心 API&#xff0c;并通过实战案例演示如何创造自然流畅的交互体验。 &#x1f9f2; 拖拽动画基础 1. 启用拖拽 使用 drag 属性即可开启拖拽能力。支持的值有&#xff1a;true&#xff08;全方向…

CF148D Bag of mice

题目传送门 思路 状态设计 设 d p i , j dp_{i, j} dpi,j​ 表示袋中有 i i i 个白鼠和 j j j 个黑鼠时&#xff0c; A A A 能赢的概率。 状态转移 现在考虑抓鼠情况&#xff1a; A A A 抓到白鼠&#xff1a;直接判 A A A 赢&#xff0c;概率是 i i j \frac{i}{i j}…

BT1120 BT656驱动相关代码示例

前些年做视频输出项目的时候用过bt1120 tx与rx模块&#xff0c;现将部分代码进行记录整理。代码功能正常&#xff0c;可正常应用。 1. rx部分&#xff1a; /****************************************************************************** Copyright (C) 2021,All rights …

服务器简介(含硬件外观接口介绍)

服务器&#xff08;Server&#xff09;是指提供资源、服务、数据或应用程序的计算机系统或设备。它通常比普通的个人计算机更强大、更可靠&#xff0c;能够长时间无间断运行&#xff0c;支持多个用户或客户端的请求。简单来说&#xff0c;服务器就是专门用来存储、管理和提供数…

SQL-exists和in核心区别​、 性能对比​、适用场景​

EXISTS和IN的基本区别。IN用于检查某个值是否在子查询返回的结果集中,而EXISTS用于检查子 查询是否至少返回了一行数据。通常来说,EXISTS在子查询结果集较大时表现更好,因为一旦找 到匹配项就会停止搜索,而IN则需要遍历整个结果集。 在 SQL 中,EXISTS 和 IN 都可以用于…

焕活身心,解锁健康养生新方式

健康养生是一门科学&#xff0c;更是一种生活智慧。从日常点滴做起&#xff0c;才能筑牢健康根基。​ 饮食上&#xff0c;应遵循 “食物多样&#xff0c;谷类为主” 原则。多摄入新鲜蔬果&#xff0c;它们富含维生素与膳食纤维&#xff0c;有助于增强免疫力&#xff1b;选择全…

QT+Cmake+mingw32-make编译64位的zlib-1.3.1源码成功过程

由于开源的软件zlib库是很多相关库libpng等基础库&#xff0c;因此掌握使用mingw编译器来编译zlib源码的步骤十分重要。本文主要是通过图文模式讲解完整的qtcmakezlib源码搭建和测试过程&#xff0c;为后续的其他源码编译环境搭建做基础准备。 详细步骤如下&#xff1a; 1、下…

健身会员管理系统(ssh+jsp+mysql8.x)含运行文档

健身会员管理系统(sshjspmysql8.x) 对健身房的健身器材、会员、教练、办卡、会员健身情况进行管理&#xff0c;可根据会员号或器材进行搜索&#xff0c;查看会员健身情况或器材使用情况。

【langchain4j】Springboot如何接入大模型以及实战开发-AI问答助手(一)

langchain4j介绍 官网地址&#xff1a;https://docs.langchain4j.dev/get-started langchain4j可以说是java和spring的关系&#xff0c;spring让我们开发java应用非常简单&#xff0c;那么langchain4j对应的就是java开发ai的 “Spring” 他集成了AI应用的多种场景&#xff0c…

平均池化(Average Pooling)

1. 定义与作用​​ ​​平均池化​​是一种下采样操作&#xff0c;通过对输入区域的数值取​​平均值​​来压缩数据空间维度。其核心作用包括&#xff1a; ​​降低计算量​​&#xff1a;减少特征图尺寸&#xff0c;提升模型效率。​​保留整体特征​​&#xff1a;平滑局部…

【dify实战】chatflow结合deepseek实现基于自然语言的数据库问答、Echarts可视化展示、Excel报表下载

dify结合deepseek实现基于自然语言的数据库问答、Echarts可视化展示、Excel报表下载 观看视频&#xff0c;您将学会 在dify下如何快速的构建一个chatflow&#xff0c;来完成数据分析工作&#xff1b;如何在AI的回复中展示可视化的图表&#xff1b;如何在AI 的回复中加入Excel报…

加一:从简单问题到复杂边界的深度思考

加一&#xff1a;从简单问题到复杂边界的深度思考 引言 在算法世界里&#xff0c;有些问题看似简单&#xff0c;实则暗藏玄机&#xff0c;其中“加一”问题就是一个典型例子。所谓“加一”&#xff0c;通常指的是给一个由数字组成的数组表示的整数加一&#xff0c;这听起来简…

PointCore——利用局部全局特征的高效无监督点云异常检测器论文与算法解读

概述 三维点云异常检测旨在从训练集中检测出异常数据点&#xff0c;是工业检测、自动驾驶等众多应用的基础。然而&#xff0c;现有的点云异常检测方法通常采用多个特征存储库来充分保留局部和全局特征表示&#xff0c;这带来了高昂的计算成本以及特征之间的不匹配问题。为解决…