【数据结构】ArrayList详解

目录

前言

1. 线性表

2. 顺序表

3. ArrayList的介绍和使用

3.1 语法格式

3.2 添加元素

3.3 删除元素

3.4 截取部分arrayList

3.5 其他方法

4. ArrayList的遍历

5.ArrayList的扩容机制

6. ArrayList的优缺点

结语


前言

在集合框架中,ArrayList就是一个普通的类,它实现了List接口。作为我们学习初阶数据结构的入门知识,ArrayList还是很好理解的,在学习它之前,我们也得先来简单了解下线性表以及顺序表

1. 线性表

线性表(Linear List)是零个或多个相同类型数据元素的有限序列。它是一种被广泛使用的数据结构,常见的线性表有:顺序表、链表、栈、队列……

线性表在逻辑上是线性结构,我们可以看作一条连续的直线,但是在物理结构上不一定是连续的,像顺序表,它在逻辑结构上和物理结构上都是连续的;而链表在物理结构上就不是连续的


2. 顺序表

从上面的图中我们可以看出,顺序表是物理结构和逻辑结构都连续的线性表,一般情况下采用数组存储,说白了,顺序表就是一个数组。ArrayList可以被认为是顺序表的一种实现


3. ArrayList的介绍和使用

3.1 语法格式

ArratList类位于java.util包当中,我们在使用前得先导包

import java.util.ArrayList;ArrayList<E> arrayList = new ArrayList<>();

又因为ArrayList实现了List接口,所以我们也可以用接口来引用ArrayList对象,List类也需要导包

import java.util.List;
import java.util.ArrayList;List<E> list = new ArrayList<>();
  • E:泛型数据类型,为可以用来限制arrayList的类型,但是只能引用数据类型
  • 对于两种arrayList的创建,我更推荐使用第一种,这样能实现的方法也会更多 

除了以上两种构造(无参),其实还有另外两种构造方法 

//指定顺序表的初始容量
ArrayList<E> arrayList = new ArrayList<>(int initialCapacity);//利用其他Collection构建ArrayList
ArrayList<E> arrayList = new ArrayList<>(Collection<? extends E> c);

我们经常使用的就是第一、二种,第三种比较少用到


3.2 添加元素

boolean add(E e):在列表尾处插入e

void add(int index,E element):将element插入到下标为index位置

        ArrayList<Integer> arrayList = new ArrayList<>();arrayList.add(1);arrayList.add(2);arrayList.add(3);System.out.println(arrayList);arrayList.add(1,200);System.out.println(arrayList);

而且我们还可以直接打印list,因为它已经重写了toString方法。运行结果如下 

boolean addAll(Collection<? extends E> c):尾插一组数据(可以是其他顺序表)

        ArrayList<Integer> arrayList1 = new ArrayList<>();arrayList1.add(1);arrayList1.add(2);arrayList1.add(3);ArrayList<Integer> arrayList2 = new ArrayList<>(arrayList1);System.out.println(arrayList2);

运行结果如下 


3.3 删除元素

E remove(int index):删除下标为index的元素

boolean remove(Object o): 删除遇到的第一个o元素

        ArrayList<Integer> arrayList = new ArrayList<>();arrayList.add(1);arrayList.add(2);arrayList.add(3);System.out.println(arrayList);arrayList.remove(1);//删除下标为1的元素arrayList.remove(Integer.valueOf(2));//删除值为2的元素System.out.println(arrayList););

 运行结果如下 

注意:当我们想通过值来删除元素的时候,传进去的值要记得装箱,也就是将基本类型转为引用类型。像上面的例子,我们想要删除元素2,就得传入Integer.valueOf(2)才能实现


3.4 截取部分arrayList

List<E> subList(int fromIndex,int toIndex):截取部分list(左闭右开)

  • 要注意,该方法返回类型为List<E>,所以我们必须用List<E>去引用过arrayList对象
  • 该方法实际上不是生成一个新的顺序表,而是直接引用了arrayList里的地址,所以当我们改变list里的值时,arrayList里的值也会发生改变
        ArrayList<Integer> arrayList = new ArrayList<>();arrayList.add(1);arrayList.add(2);arrayList.add(3);//截取部分list [左闭右开)List<Integer> list = arrayList.subList(0,2);System.out.println(list); //1,2//但是它并不是重新生成,而是指向同一引用list.set(0,100);System.out.println(arrayList);//arrayList里的元素也会被改变

运行结果如下

3.5 其他方法

有需要时就直接查询, 文档链接:ArrayList (Java SE 17 和 JDK 17) (oracle.com)


4. ArrayList的遍历

ArrayList有三种遍历方法:

  1. for循环
  2. foreach循环
  3. 使用迭代器
        ArrayList<Integer> arrayList = new ArrayList<>();arrayList.add(1);arrayList.add(2);arrayList.add(3);//打印一:forfor (int i = 0; i < arrayList.size(); i++) {System.out.print(arrayList.get(i)+" ");}//打印二:foreachfor (Integer x : arrayList) {System.out.print(x + " ");}System.out.println();

 运行结果如下


使用迭代器打印,我们就只能使用List<E>接口来引用arrayList,还有要导包

import java.util.Iterator; import java.util.ListIterator;

        //打印三:迭代器//默认是从 0 下标开始打印System.out.println("===Iterator===");Iterator<Integer> it =  arrayList.iterator();//创建迭代器while (it.hasNext()) {System.out.print(it.next() +" ");}System.out.println();System.out.println("===listIterator倒着打印===");//从 指定位置 开始打印     list1.size()ListIterator<Integer> it2 =  arrayList.listIterator(arrayList.size());while (it2.hasPrevious()) {System.out.print(it2.previous() +" ");}System.out.println();

运行结果如下

这个方法适当了解就行 


5.ArrayList的扩容机制

在前面的学习中,我们使用到了add()方法来添加元素,但我们在创建顺序表的时候却没有给它指定容量大小,它的大小肯定为0,那为什么还能正常添加而不报错呢?

其实ArrayList它是一个动态类型的顺序表,我们在插入元素的过程中,它会自动扩容,因此不需要我们担心容量太小而不够添加元素

6. ArrayList的优缺点

优点:因为ArrayList是一个顺序表,非常适合根据下标查找和更新的场景,此时的时间复杂度为O(1)

缺点:也正是因为ArrayList是一个顺序表,因此当我们想在任意位置插入或删除元素时,往往需要将后面一堆的元素进行移动,时间复杂度为O(n);再则,当我们想要存放数据是,它的扩容机制是为1.5倍或2倍扩容,这样可能会导致内存空间的浪费

结语

今天我们一起学习了ArrayList,知道了它的构造,使用方法,优缺点……而想要解决ArrayList的痛点,我们可以使用链表来规避这些问题,这就是我们下篇博文要写的内容,敬请期待吧

希望大家能喜欢这篇文章,有总结不到位的地方还请多多谅解,若有出现纰漏,希望大佬们看到错误之后能够在私信或评论区指正,博主会及时改正,共同进步!

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

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

相关文章

spring boot学习第十六篇:配置多数据源

1、代码参考&#xff1a; dynamic-ds/spring-boot-dynamic-ds at main veminhe/dynamic-ds GitHub 2、验证 2.1调用POST接口http://localhost:8081/hmblogs/blog/addBlog 2.2改动数据源为BJ 然后调用接口添加数据 然后查看ds0库的博客数据

【最新可用】Claude国内镜像,可上传图片,可用Claude3全系模型(包括Pro版本的Opus)!亲测比GPT好用!

亲测可用&#xff0c;镜像地址&#xff1a;Claude 3 镜像 使用方法 访问镜像&#xff1a;Claude 3 镜像 2. 点击设置&#xff0c;配置授权码&#xff0c;关闭设置。这里免费赠送一个体验版的授权码 sk-SZcJyvx3RXRID624E2D3795578Df44C7Af03F2909a8f5eA0 即可发起对话啦&…

Android Studio学习9——使用Logcat打印日志

在Android开发中&#xff0c;Logcat是一个工具&#xff0c;它允许开发者查看设备或模拟器的日志信息。开发者可以使用Log类来打印日志信息&#xff0c;这对于调试和错误排查非常有帮助。 v 或 verbose: 最低等级&#xff0c;显示所有消息。d 或 debug: 用于调试消息。i 或 info…

深入浅出 -- 系统架构之负载均衡Nginx动静分离

一、Nginx动静分离 动静分离应该是听的次数较多的性能优化方案&#xff0c;那先思考一个问题&#xff1a;为什么需要做动静分离呢&#xff1f;它带来的好处是什么&#xff1f; 其实这个问题也并不难回答&#xff0c;当你搞懂了网站的本质后&#xff0c;自然就理解了动静分离的重…

Docker安装mysql并且设置主从

Docker安装部署mysql 下载镜像 docker pull mysql:5.7.35查看镜像 docker images启动 直接启动不挂载文件 docker run -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD123456 -d mysql:5.7.35挂载文件 docker run -p 3306:3306 --name mysql \ -v /usr/local/docker/m…

【Linux】环境基础开发工具使用——gcc/g++使用

Linux编译器-gcc/g使用 1. 背景知识 1. 预处理&#xff08;进行宏替换 ) 2. 编译&#xff08;生成汇编 ) 3. 汇编&#xff08;生成机器可识别代码&#xff09; 4. 连接&#xff08;生成可执行文件或库文件 ) 2. gcc如何完成 格式 gcc [ 选项 ] 要编译的文件 [ 选…

代码随想录第19天

654. 最大二叉树 已解答 中等 相关标签 相关企业 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点&#xff0c;其值为 nums 中的最大值。递归地在最大值 左边 的 子数组前缀上 构建左子树。递归地在最大值 右边 的 子数组后缀…

Linux shell编程学习笔记45:uname命令-获取Linux系统信息

0 前言 linux 有多个发行版本&#xff0c;不同的版本都有自己的版本号。 如何知道自己使用的Linux的系统信息呢&#xff1f; 使用uname命令、hostnamectl命令&#xff0c;或者通过查看/proc/version文件来了解这些信息。 我们先看看uname命令。 1 uname 命令的功能和格式 …

官方竞价排名是否对SEO自然排名有影响?

很多站长有疑问&#xff0c;如果使用搜索引擎官方的SEM竞价&#xff0c;是否对之前做的SEO自然优化排名有影响。这个问题我自己也有疑问。 因为很多站长认为是起绝对反作用&#xff0c;什么只要用了竞价&#xff0c;停止之后&#xff0c;原本很好的排名都会掉光。我们不否定一…

Linux:部署搭建zabbix6(1)

1.基础介绍 Zabbix&#xff1a;企业级开源监控解决方案https://www.zabbix.com/cn这个是zabbix的官网&#xff0c;你可以进去看到由官方给你提供的专业介绍和获取到最新版本的功能介绍&#xff0c;还有各种安装&#xff0c;由于官方安装是多种复杂的&#xff0c;我这里就单独挑…

【stm32】软件I2C读写MPU6050

软件I2C读写MPU6050(文章最后附上源码) 编码 概况 首先建立通信层的.c和.h模块 在通信层里写好I2C底层的GPIO初始化 以及6个时序基本单元 起始、终值、发送一个字节、接收一个字节、发送应答、接收应答 写好I2C通信层之后&#xff0c;再建立MPU6050的.c和.h模块 基于I2C通…

Python基于深度学习的屋内烟雾检测系统的研究与实现,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

【原创】springboot+vue校园座位预约管理系统设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

RankLLM:RAG架构下通过重排序实现精准信息检索

一、前言 在检索增强生成&#xff08;Retrieval-Augmented Generation, RAG&#xff09;的框架下&#xff0c;重排序&#xff08;Re-Rank&#xff09;阶段扮演着至关重要的角色。该阶段的目标是对初步检索得到的大量文档进行再次筛选和排序&#xff0c;以确保生成阶段能够优先…

特征融合篇 | RTDETR引入基于内容引导的特征融合方法 | IEEE TIP 2024

本改进已集成到 RT-DETR-Magic 框架。 摘要—单幅图像去雾是一个具有挑战性的不适定问题,它从观察到的雾化图像中估计潜在的无雾图像。一些现有的基于深度学习的方法致力于通过增加卷积的深度或宽度来改善模型性能。卷积神经网络(CNN)结构的学习能力仍然未被充分探索。本文提…

一周年纪念

文章目录 机缘&#xff1a;命运之门收获---知识之心日常---灵魂之窗成就 — 自我之光憧憬 — 未来之路 机缘&#xff1a;命运之门 “人生是由一连串的选择组成&#xff0c;而真正的成长&#xff0c;往往始于最具挑战性的决定。” —— 这句话恰如其分地概括了我选择跨考计算机的…

【C++】map set 底层刨析

文章目录 1. 红黑树的迭代器2. 改造红黑树3. map 的模拟实现4. set 的模拟实现 在 C STL 库中&#xff0c;map 与 set 的底层为红黑树&#xff0c;那么在不写冗余代码的情况下使用红黑树同时实现 map 与 set 便是本文的重点。 1. 红黑树的迭代器 迭代器的好处是可以方便遍历&…

数据结构--树和二叉树

树和二叉树 1.树概念及结构树的概念树的相关概念树的表示 2.二叉树概念及结构概念特殊的二叉树二叉树的性质 3.二叉树顺序结构及实现4.二叉树链式结构及实现二叉树的顺序结构二叉树的前&#xff0c;中&#xff0c;后序遍历层序遍历 1.树概念及结构 树的概念 树是一种非线性的…

SSL协议是什么?有什么作用?

SSL协议是一种让互联网上的数据传输变得更安全的技术。它的主要作用是&#xff1a; 保密性&#xff1a; 使用加密手段&#xff0c;让别人偷看不了你在网上发的信息&#xff08;比如密码、聊天内容、银行卡号等&#xff09;。完整性&#xff1a;防止你的信息在传输途中被偷偷修…

九州金榜|孩子叛逆,家长应该怎么办?

孩子是父母的宝贝&#xff0c;孩子快乐&#xff0c;作为父母就会快乐&#xff0c;每位家长都希望自己的孩子健康快乐长大。孩子在成长的过程中&#xff0c;随着年龄以及阅历的增长&#xff0c;都会出现叛逆&#xff0c;孩子出现叛逆&#xff0c;对于父母来说是一种挑战&#xf…