数据结构(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.mfbz.cn/a/743928.html

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

相关文章

etcd详解

一、etcd概要 1.etcd的简介 在做微服务集群开发时&#xff0c;有很多应用&#xff0c;有很多微服务上下游节点&#xff0c;它们本身需要很多存储配置文件&#xff0c;需要有一个地方来存储这些配置文件&#xff0c;因此诞生了etcd&#xff0c;它本质是为了微服务上下游服务去…

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

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

20240626 每日AI必读资讯

&#x1f30d;警告&#xff01;OpenAI宣布全面封锁中国API接入&#xff01; - 7月9号开始封锁不支持的国家API - 如果在OpenAI不允许的国家使用其 API 将面临封杀 &#x1f517; 警告&#xff01;OpenAI 宣布全面封锁中国 API 接入-CSDN博客 &#x1f3b5;索尼、环球音乐、华…

NTFS和exFAT哪个性能好 U盘格式化NTFS好还是exFAT好 mac不能读取移动硬盘怎么解决

文件系统的选择对存储设备的性能和兼容性有着重要影响。而NTFS和EXFAT作为两种常见的文件系统&#xff0c;它们各有特点&#xff0c;适用于不同的使用场景。我们将深入探讨NTFS和EXFAT的区别&#xff0c;帮助大家选择最适合自己需求的文件系统。 NTFS&#xff1a;稳定与性能的平…

SAP ABAP 之OOALV

文章目录 前言一、案例介绍/笔者需求二、SE24 查看类 a.基本属性 Properties b.接口 Interfaces c.友元 Friends d.属性 Attributes e.方法 Methods f.事件 Events g.局部类型 Types …

[20] Opencv_CUDA应用之 关键点检测器和描述符

Opencv_CUDA应用之 关键点检测器和描述符 本节中会介绍找到局部特征的各种方法&#xff0c;也被称为关键点检测器关键点(key-point)是表征图像的特征点&#xff0c;可用于准确定义对象 1. 加速段测试特征功能检测器 FAST算法用于检测角点作为图像的关键点&#xff0c;通过对…

【zabbix】zabbix 自动发现与自动注册、proxy代理

1、配置zabbix自动发现&#xff0c;要求发现的主机不低于2台 zabbix 自动发现&#xff08;对于 agent2 是被动模式&#xff09; zabbix server 主动的去发现所有的客户端&#xff0c;然后将客户端的信息登记在服务端上。 缺点是如果定义的网段中的主机数量多&#xff0c;zabbi…

DIY 智能门禁:用 ESP32 RFID 打造安全便捷的家居体验 (附代码)

一、系统概述 本项目旨在使用 ESP32 微控制器和 RFID 技术构建一个安全可靠的门禁系统。该系统利用 RFID 卡进行身份验证&#xff0c;通过读取卡内存储的唯一 ID&#xff0c;判断用户权限并控制门锁的开关。ESP32 强大的 Wi-Fi 功能还能实现远程监控和管理&#xff0c;方便用户…

【C++进阶学习】第四弹——多态——迈向C++更深处的关键一步

前言&#xff1a; 在前面我们已经学习了C中继承的相关知识&#xff0c;已经体会到C在与C语言的对比中的便捷性&#xff0c;但是有一些问题并没有被解决&#xff0c;比如继承中如何使不同的派生类公用基类的一个函数&#xff0c;这就需要多态的知识&#xff0c;而且&#xff0c;…

项目实训-vue(十二)

项目实训-vue&#xff08;十二&#xff09; 文章目录 项目实训-vue&#xff08;十二&#xff09;1.概述2.处理进度可视化 1.概述 本篇博客将记录我在图片上传页面中的工作。 2.处理进度可视化 除了导航栏之外&#xff0c;我们还需要对上传图片以及图片处理的过程以及流程进行…

今日分享:能源行业数据大屏与界面设计~

能源行业数据大屏设计时要紧扣行业主题&#xff0c;关注视觉效果、实时数据与动态效果、数据可视化和图表、布局与字体、交互性、告警功能、故事叙述、易读性和可维护性等多个方面。大家设计时可以从这几个方面进行检查调整&#xff0c;这样就可以设计出既美观又实用的能源行业…

mulesoft --环境安装与搭建

1.mavenjdkpostman 2.anypoint statdio 下载安装 下载 Anypoint Studio & Mule |骡子软件 (mulesoft.com) 填好基本信息后&#xff0c;会发邮件&#xff0c;在邮件中下载&#xff0c;跳到官网下载 3注册账号 Download Anypoint Studio & Mule | MuleSoft 4.Connect…

昇思25天学习打卡营第2天 | 张量Tensor

张量Tensor 张量&#xff08;Tensor&#xff09;基础 张量是MindSpore中的基本数据结构的一种&#xff0c;类似于NumPy中数组和矩阵非常相似。它具有以下重要属性&#xff1a; 形状&#xff08;shape&#xff09;和数据类型&#xff08;dtype&#xff09;&#xff1a;每个张量…

Windows安装配置jdk和maven

他妈的远程连接不上公司电脑&#xff0c;只能在家重新配置一遍&#xff0c;在此记录一下后端环境全部配置 Windows安装配置JDK 1.8一、下载 JDK 1.8二、配置环境变量三、验证安装 Windows安装配置Maven 3.8.8一、下载安装 Maven并配置环境变量二、设置仓库镜像及本地仓库三、测…

综合例题-求最小函数依赖集、确定候选键、判断最高满足的范式、模式分解

一、综合例题&#xff1a; 二、分析&#xff1a; 1、在函数依赖的范畴内&#xff0c;要掌握Armstrong公理的推理规则 2、利用推理规则计算属性集闭包和函数依赖集闭包 3、从而寻找与给定的函数依赖集等价的最小函数依赖集 4、在最小函数依赖集的基础上&#xff0c;确定候选…

瑜伽馆管理系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;教练管理&#xff0c;用户管理&#xff0c;瑜伽管理&#xff0c;套餐管理&#xff0c;体测报告管理&#xff0c;基础数据管理 前台账户功能包括&#xff1a;系统首页&#xff0…

【Containerd】Containerd接入Harbor仓库

说明 在日常使用容器时&#xff0c;安全方便起见一般都会使用到私有仓库&#xff0c;一般都是采用 harbor 作为私有仓库&#xff0c;docker 对接 harbor 仓库非常简单&#xff0c;那么 containerd 如何对接 harbor 呢&#xff1f; 在内网使用 harbor 根据个人习惯&#xff0c…

【ai】jetson:编译安装CUDA工具

编译安装CUDA工具 jetson cuda 检测GPU信息 进入/usr/local/cuda-10.2/samples/1_Utilities 0_Simple 1_Utilities 2_Graphics 3_Imaging 4_Finance 5_Simulations 6_Advanced 7_CUDALibraries common EULA.txt Makefile nvidia@tx2-nx:/usr/local/cuda-10.2/sample…

【日常记录】【JS】优雅检测用户是否在指定元素的外部点击

文章目录 1、界面基本布局2、代码实现3、参考链接 1、界面基本布局 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0">…