数据结构(Java):顺序表集合类ArrayList

1、线性表

线性表,在逻辑结构上是连续的(可理解为连续的一条直线,一对一的关系),而在物理结构上不一定连续,通常以数组和链式结构进行存储。

线性表是一种在实际中广泛使用的数据结构,常见的线性表有:顺序表、链表、栈、队列......

2、顺序表

顺序表是线性表的一种,其物理地址是连续的,采用数组的的存储结构,在数组上完成数据的增删查改。

3、集合类ArrayList

在Java集合框架中,ArrayList是一个泛型类,并且实现了List接口,是Java为我们封装好的顺序表。

当我们想存储哪种类型的元素时,都可以通过泛型传参来构建相应类型的顺序表

接下来,让我为大家仔细讲解一下ArrayList这个集合类。

3.1 ArrayList的成员变量

我们通过观察ArrayList的源码,得到其成员变量如下:

已知,DEFAULT_CAPACITY是指默认容量(10),elementData是用来实际存储数据的数组,size记录顺序表数据的数量,剩下的两个数组均为空数组。

想要知道他们的用途,我们还需要观察ArrayList的构造方法。

3.2 ArrayList的构造方法

通过观察源码,我们依然可以得出其构造方法:

接下来,我们逐个分析。

3.2.1 带参构造之public ArrayList(int initialCapacity)

不难看出,我们传入的参数就是我们初始化顺序表时的容量(即大小)。

通过if-else语句可以看出:

1.传入的参数为正数时,初始化的大小即为参数值。

2.传入的参数为0时,该顺序表数组的引用指向的就是成员变量中的空数组。

3.传入的参数为负数时,则会抛出异常(数组大小肯定为正数)。

public static void main(String[] args) {ArrayList<Integer> list = new ArrayList<>(10);//初始容量为10}

3.2.2 无参构造之public ArrayList()

这个构造方法就更简单了,无参构造时,该顺序表数组的引用指向的也是成员变量中的空数组。

public static void main(String[] args) {ArrayList<Integer> list = new ArrayList<>();}

3.2.1 带参构造之public ArrayList(Collection<? extends E> c)

大家看到这个构造方法时,是不是愣住了一下子,哈哈哈~,不要慌张,听我道来。

我们先来看这个参数CollectionCollection是一个接口,不知道大家是否还有印象,它曾出现在集合框架中的顶层:

而<>中的内容,"?"是指通配符(这里了解即可),extends我们在讲解泛型时就已经知道,这规定了通配符的上界为E。

也就是说,该构造方法所传参数必须满足以下几点:

1.实现了Collection接口

2.所具备的泛型必须是E或者E的子类

也就说,我们也可以将另一个顺序表当做这个顺序表构造方法的参数传入。

代码示例:

public static void main(String[] args) {ArrayList<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);ArrayList<Integer> list1 = new ArrayList<>(list);//将list当做顺序表构造方法的参数传入list1.add(99);list1.add(100);System.out.println(list1);//[1, 2, 3, 99, 100]}

3.3 ArrayList的扩容机制

在上面讲顺序表的构造方法时,我们讲当构造方法为无参构造或者传入的参数为零时,数组是空数组。既然是空数组,那么我们如何进行数据的添加或者插入呢?以及当数组容量满时,如何进行数据的添加或者插入呢?

实际上,当无参构造或者传入的参数为零时,经过源码的处理,也是将数组的初始容量设置成了DEFAULT_CAPACITY(10)。

且,ArrayList是一个动态顺序表,即:在插入元素的过程中会以1.5倍自动扩容(调用Arrays的copyOf方法进行扩容)。

3.4 ArrayList的常用方法

ArrayList提供了很多的方法,在这里,我将列举较常用的方法。

3.4.1 add方法(数据插入)

该方法实现了重载,分别在顺序表尾部插入和在指定下标位置插入。

3.4.1.1 尾部插入数据

方法格式:

代码示例:

3.4.1.2 指定位置插入数据

方法格式:

代码示例:

3.4.2 addAll方法

方法格式:

同样的道理,传入的参数必须实现了Collection接口,并且其泛型参数的上界为E(上文已经进行了讲解)。

调用该方法,可以将参数的数据尾插到当前顺序表当中。

代码演示:

3.4.3 remove方法(数据删除)

3.4.3.1 删除指定下标数据

方法格式:

注意:该方法的返回值,为所删除的数据。

3.4.3.2 删除确定数值的数据

方法格式:

因为ArrayList是一个泛型类,数组中的元素都为一个对象,所以我们应该传入相应类型的对象作为参数。

代码示例:

注意:我们看到,remove方法中的参数被划上了横线,这说明该方法的这种传参调用方式被废弃了(不常用了),但是我们仍然可以使用。

3.4.4 get方法(获取数据)

方法格式:

传入下标,返回指定下标的数据。

3.4.5 set方法(修改数据)

方法格式:

修改指定下标的数据。、

3.4.6 set方法(清空顺序表)

方法格式:

 

该方法的底层就是:将有效数据修改为null(各元素为引用类型),再将size(数组大小)置为0。

3.4.7 subList方法(截取顺序表)

方法格式:

该方法能够截取顺序表的指定区间(区间为左闭右开),并返回截取后的顺序表(注意:返回类型为List,是ArrayList实现的一个接口)。

代码示例:

需要注意的,新截取的顺序表list1和原来的顺序表list,指向的的是同一块空间:

也就是说,修改顺序表list1中的数据,list中的数据也会被修改。

3.5 ArrayList的遍历

3.5.1 for循环遍历

代码示例:

public static void main(String[] args) {ArrayList<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);int size = list.size();for (int i = 0; i < size; i++) {int data = list.get(i);//得到i下标的元素System.out.print(data+" ");}System.out.println();}

3.5.2 for-each循环遍历

因为顺序表实际上是个数组,我们可以通过for-each循环来遍历顺序表:

public static void main(String[] args) {ArrayList<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);for (int data : list) {System.out.print(data+" ");}}

3.5.3 迭代器遍历

3.5.3.1 Iterator迭代器

在ArrayList中,存在iterator方法:

通过调用这个方法,我们可以得到一个迭代器对象,再通过这个对象将数据一个一个打印,直到全部打印完成。

public static void main(String[] args) {ArrayList<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);Iterator<Integer> iterator =  list.iterator();while (iterator.hasNext()) {//hasNext方法 用来判断是否有下一个数据int data = iterator.next();//next方法是 得到下一个数据System.out.print(data+" ");}}

hasNext方法 用来判断是否有下一个数据。

next方法是 得到下一个数据。

3.5.3.2 ListIterator迭代器

与Iterator迭代器用法相同,我们可以通过listIterator来遍历顺序表:

public static void main(String[] args) {ArrayList<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);ListIterator<Integer> listIterator = list.listIterator();while (listIterator.hasNext()) {int data = listIterator.next();System.out.print(data+" ");}}
3.5.3.3  Iterator迭代器和ListIterator迭代器的关系

首先,这两者均为接口

其次,我们通过源码可以发现,ListIterator拓展了Iterator,也就是说,ListIterator迭代器拓展了Iterator迭代器的功能,其方法更加丰富。

3.5.3.3.1 ListIterator迭代器的新增功能

这里,我们演示一个ListIterator的新增方法。

通过源码,我们可以发现ArrayList的listIterator方法可以传入参数,

调用listIterator方法并传入参数,得到的迭代器就会来到该下标的元素之后的位置,

我们再使用ListIterator新增的hasPrevious和previous方法就可以实现对顺序表从后往前的遍历:

代码:

public static void main(String[] args) {ArrayList<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);int size = list.size();ListIterator<Integer> listIterator = list.listIterator(size);while (listIterator.hasPrevious()) {int data = listIterator.previous();System.out.print(data+" ");}}

OK~本次博客到这里就结束了,

感谢大家的阅读~欢迎大家在评论区交流问题~

如果博客出现错误可以提在评论区~

创作不易,请大家多多支持~

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

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

相关文章

Vue介绍与入门(一篇入门)

Vue.js 是一个流行的 JavaScript 框架&#xff0c;专门用于构建用户界面和单页面应用程序。它简单易学&#xff0c;但功能强大&#xff0c;能够帮助开发者快速构建交互性强的 Web 应用。 本教程旨在帮助那些刚开始学习 Vue.js 的开发者快速入门&#xff0c;并掌握一些基础知识…

【UE5.1 角色练习】12-坐骑——Part2(让角色骑上坐骑)

目录 前言 效果 步骤 一、坐骑的父类 二、将角色附加到坐骑 三、添加坐姿 四、骑上坐骑 五、从坐骑上下来 前言 在上一篇&#xff08;【UE5.1 角色练习】11-坐骑——Part1&#xff08;控制大象移动&#xff09;&#xff09;基础上继续实现角色骑上坐骑的功能。 效果 …

语言的数据结构:树与二叉树(二叉树篇)

语言的数据结构&#xff1a;树与二叉树&#xff08;二叉树篇&#xff09; 前言概念特别的二叉树满二叉树完全二叉树 存储结构顺序存储链式存储 查找方式 前言 上文说到了树&#xff0c;有人认为二叉树是树的每一个分支都有两个子节点。其实这也对。但二叉树在此基础上还做了限…

【QCustomPlot实战系列】QCPGraph区域高亮

使用QCPDataSelection来设置选中的区域&#xff0c;并将QCPGraph的可选择区域设置成QCP::stMultipleDataRanges void AreaPieces::initCustomPlot(QCustomPlot *parentPlot) {QVector<double> x {0, 1, 2, 3, 4, 5, 6, 7, 8};QVector<double> y {200, 560, 750…

《mysql篇》--mysql常用命令

数据库操作 显示当前数据库 show databases;(database 后面要加s) 这行命令用来显示当前有多少个数据库 //mysql中有自带的四个库 创建数据库 create database 数据库名(name); 创建一个数据库 create dabase if not exists <数据库名(name)>; //如果系统有与当前创建…

前端vite+vue3——利用环境变量和路由区分h5、pc模块打包(从0到1)

⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享 前端vitevue3——利用环境变量和路由对前端区分h5和pc模块打包&#xff08;从0到1&#xff09;。 背景&#xff1a; 前端本地开发pc和h5的项目&#xff0c;发布时需要区分开h5和pc的页面 vite Vite 通过在一开始将应…

图片怎么加水印?快来试试这6个图片加水印方法(2024年新)

图片怎么加水印&#xff1f;作为打工人在日常的工作生活中总会遇到各种各样的工作难题&#xff0c;相信从事电商或者是设计等工作的小伙伴们&#xff0c;遇到最多的问题应该就是给图片添加水印了。为什么要给图片加水印&#xff1f;其实给图片加水印最主要的目的是保护我们的图…

一文入门Makefile

今天我们来玩玩Makefile。 这边是借鉴的陈皓老师的《跟我一起写 Makefile》 pdf下载链接如下。 链接&#xff1a;https://pan.baidu.com/s/1woRq2nEkgzLv1o5uE0FZHg?pwdmhrh 提取码&#xff1a;mhrh 我们之前已经算是入门了gcc&#xff0c;那我们的下一站就是Makefile&…

嵌入式学习(Day 51:ARM指令/汇编与c语言函数相互调用)

1.Supervisor模式与SVC模式 Supervisor模式是ARM处理器的一个特权工作模式&#xff0c;允许执行特权指令和访问特权资源。SVC模式&#xff08;Supervisor Call&#xff09;是与Supervisor模式相关的一个功能或指令&#xff0c;用于从用户模式切换到Supervisor模式&#xff0c;…

大模型应用研发基础环境配置(Miniconda、Python、Jupyter Lab、Ollama等)

老牛同学之前使用的MacBook Pro电脑配置有点旧&#xff08;2015 年生产&#xff09;&#xff0c;跑大模型感觉有点吃力&#xff0c;操作起来有点卡顿&#xff0c;因此不得已捡起了尘封了快两年的MateBook Pro电脑&#xff08;老牛同学其实不太喜欢用 Windows 电脑做研发工作&am…

从零开始做题:老照片中的密码

老照片中的密码 1.题目 1.1 给出图片如下 1.2 给出如下提示 这张老照片中的人使用的是莫尔斯电报机&#xff0c;莫尔斯电报机分为莫尔斯人工电报机和莫尔斯自动电报机&#xff08;简称莫尔斯快机&#xff09;。莫尔斯人工电报机是一种最简单的电报机&#xff0c;由三个部分组…

SelfReg-UNet:解决UNet语义损失,增强特征一致性与减少冗余的优化模型

SelfReg-UNet&#xff1a;解决UNet语义损失&#xff0c;增强特征一致性与减少冗余的优化模型 提出背景拆解类比&#xff1a;整理书架语义一致性正则化内部特征蒸馏为什么 UNet 会有语义损失&#xff1f; 提出背景 论文&#xff1a;https://arxiv.org/pdf/2406.14896 代码&…

c++内存管理_复习

new与placement new new&#xff1a; 先调用operator new(大小)&#xff0c;而operator new()会调用malloc尝试分配内存&#xff0c;失败则调用_callnewh()来释放内存&#xff0c;直至分配成功 可以设置分配失败的处理函数&#xff1a;将写好的处理函数作为参数传入set_new_han…

Vue3 使用 Vue Router 时,params 传参失效

前言&#xff1a; 在写项目的时候&#xff0c;使用了 vue-router 的 params 进行传参&#xff0c;但是在详情页面中一直获取不到参数。原因&#xff1a;Vue Router 在2022-8-22的那次更新后&#xff0c;使用这种方式在新页面上无法获取&#xff01; 正文&#xff1a; 在列表页进…

虚拟机装入kali linux

VMware 首先需要先安装VMware Workstation Pro可以根据这篇文章来下载VMware 下载kali linux Installer Images VS Virtual Machines Installer Images&#xff08;安装镜像&#xff09;Virtual Machines&#xff08;虚拟机&#xff09; 直接访问硬件&#xff0c;定制内核…

Matlab|【防骗帖】考虑时空相关性的风电功率预测误差建模与分析

目录 1 主要内容 2 部分程序 3 下载链接 1 主要内容 这个程序《考虑时空相关性的风电功率预测误差建模与分析》画的图片非常漂亮&#xff0c;和原文献基本一致&#xff0c;但是实际上内容并未实现出来&#xff0c;主要就是利用现有的风电预测的数据和结果做了相关的图&#…

【数据结构】(C语言):链表

链表&#xff1a; 基本单位是节点。节点至少两部分&#xff1a;数据&#xff0c;下一个数据的地址。头指针head&#xff0c;始终指向链表的第一个节点。若没有节点&#xff0c;则headNULL。链表在内存中是非连续的。不能使用索引&#xff08;下标&#xff09;查找元素。只能从…

解决:Xshell通过SSH协议连接Ubuntu服务器报“服务器发送了一个意外的数据包,received:3,expected:20”

下图所示&#xff1a; 日志也基本看不出来问题在哪&#xff0c;只是说断开了连接大概是验证失败。有幸在某论坛评论区找到了原因&#xff0c;是因为我的xshell版本太低了而服务器的ssh版本太高&#xff0c;高版本的ssh默认屏蔽了一部分不太安全的算法导致建立连接的时候验证失败…

C++ 14新特性个人总结

variable templates 变量模板。这个特性允许模板被用于定义变量&#xff0c;就像之前模板可以用于定义函数或类型一样。变量模板为模板编程带来了新的灵活性&#xff0c;特别是在定义泛化的常量和元编程时非常有用。 变量模板的基本语法 变量模板的声明遵循以下基本语法&am…

解决Vue+Vite打包后Leaflet的marker图标不显示的问题

前言 用Leaflet写关于WebGIS的开发&#xff0c;用Vite或者webpack打包&#xff0c;打包后会找不到图标&#xff0c;如下所示。 直言的说&#xff0c;笔者去网上搜了搜&#xff0c;其实收到一个比较好是答案。网址如下。 &#xff08;完美解决~&#xff09;关于VueLeaflet添加…