ArrayList与顺序表的简单理解

 前言----list

         在集合框架中,List是一个接口,继承自Collection。Collection也是一个接口,该接口中规范了后序容器中常用的一些方法,具体如下所示:

                

        Iterable也是一个接口,表示实现该接口的类是可以逐个元素进行遍历的,具体如下: 

             

        从数据结构的角度来看,List就是一个线性表,即n个具有相同类型元素的有限序列,在该序列上可以执行增删 改查以及变量等操作。 

        要知道List是个接口,并不能直接用来实例化。 如果要使用,必须去实例化List的实现类。在集合框架中,ArrayList和LinkedList都实现了List接口,具体使用参考下文。

1.线性表

        线性表(linear list)是n个具有相同特性的数据元素的有限序列

        线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列... 线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。

2.顺序表

        顺序表是用一段物理地址连续存储单元依次存储数据元素线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。

3. ArrayList简介

        在集合框架中, ArrayList 是一个普通的类,实现了 List 接口,具体框架图如下:

                       

【说明】

        1. ArrayList是以泛型方式实现的,使用时必须要先实例化

        2. ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问 

        3. ArrayList 实现了 Cloneable 接口,表明 ArrayList 是可以 clone 的
        4. ArrayList 实现了 Serializable 接口,表明 ArrayList 是支持序列化的
        5. 和 Vector 不同, ArrayList 不是线程安全的,在单线程下可以使用,在多线程中可以选择 Vector 或者 CopyOnWriteArrayList
        6. ArrayList 底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表(物理地址连续存储单元依次存储数据元素线性结构

3.1 ArrayList的构造

        1ArrayList()--->空参构造

 public static void main(String[] args) {ArrayList<Integer> arrayList = new ArrayList<>();arrayList.add(2023);arrayList.add(11);arrayList.add(28);}

        底层代码逻辑:

 

        2.2ArrayList(Collection<? extends E> c)-------->利用其他 Collection 构建 ArrayList

        <? extends E>------------------------------>
        该语句规定了ArrayList类的类型上界,即被用来存储到arraylist类中数组空间elementdata里的元素的类型上限是E,后面定义要被装载的元素类型必须是E本身或者E的子类。 

public static void main(String[] args) {ArrayList<Integer> list = new ArrayList<>();list.add(-1);list.add(100);list.add(200);ArrayList<Number> list12 = new ArrayList<>(list);list12.add(-100);System.out.println(list12);}

        代码执行结果如下图所示: 

 

        我们构造的list(1、实现了 collection接口,能够支持一些规范的容器操作;2、是支持小于等于interger类数据的存储),可以传递到list12里(1、list12实现了collection接口,2、它支持的数据类型<=number,已知interger< number)

        2.3ArrayList(int initialCapacity)----->指定顺序表初始容量

 public static void main(String[] args) {ArrayList<Integer> arrayList = new ArrayList<>(2);arrayList.add(100);arrayList.add(200);}

源码分析: 

           

 all in all:

3.2 ArrayList常见操作

        一般来说常见的方法如下图所示:

        下面来对一些较为重要的方法通过源代码来进行分析:

        1.boolean add(E e) ------>尾插 e

       

        首先arraylist的底层设置,默认容量为10;

        当我们执行完成以上代码的第一句时,虽然我们有默认为10的存储空间,但是当前却没有给顺序表list分配;当执行完第二句(即第一句add语句)时,我们才会分配一个容量为10的空间给list;

        当我们一直执行add操作,为了确保一直有存储空间来存储数据,在每一次add语句执行添加元素之前,语句会提前检查剩余的容量是否足够,当容量不足以存储数据时,会提前对空间容量进行扩容,且扩容是在前一个容量的数量上乘以1.5(即1.5倍扩容)

        具体如下图展示:

        小结:
        1. 检测是否真正需要扩容之后,最后是通过调用 grow 进行扩容
        2. 预估需要库容的大小 初步预估按照1.5 倍大小扩容
(1、初步预估按照1.5倍大小扩容 ;2、如果用户所需大小超过预估1.5倍大小,则按照用户所需大小扩容;3、 真正扩容之前检测是否能扩容成功,防止太大导致扩容失败)
        3. 也可以使调用copyOf 方法进行扩容

        2. void add(int index, E element)

        在 list 的 index 位置插入指定元素, index 及后续的元素统一往后移动一个位置,下图为底层原码:

         3.List<E> subList(int fromIndex, int toIndex) ---->

        理解:使用list中[0, 4)之间的元素构成一个新的SubList返回,但是和ArrayList共用一个elementData数组;Sub:截取产生的list,不是新产生的,而是直接将原来list相对应位置的地址传递到新的list当中。

 public static void main(String[] args) {ArrayList<Integer> arraylist = new ArrayList<>();arraylist.add(2023);arraylist.add(11);arraylist.add(28);List<Integer> sub = arraylist.subList(1, 3);System.out.println(sub);sub.set(0,100000);System.out.println(sub);System.out.println(arraylist);}

        运行结果展示: 

 

        该操作构成一个新的list返回,但是和arrayList共用一个数组,不会产生一个新的对象,所以在新list上进行修改数值时,由于指向的部分引用相同,会导致就list的数值也会发生变化。 如下下图分析所示:

 

3.3 ArrayList的遍历

        ArrayList 可以使用三方方式遍历:for循环、foreach、使用迭代器 

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遍历
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i) + " ");
}
System.out.println();
// 借助foreach遍历
for (Integer integer : list) {
System.out.print(integer + " ");
}
System.out.println();
Iterator<Integer> it = list.listIterator();
while(it.hasNext()){
System.out.print(it.next() + " ");
}
System.out.println();
}

        关于迭代器:

4. ArrayList的优缺点

        由于其底层是一段连续空间,当在ArrayList任意位置插入或者删除元素时,就需要将后序元素整体往前或者往后搬移,时间复杂度为O(n),效率比较低,因此ArrayList不适合做任意位置插入和删除比较多的场景,下面是详细的总结:

缺点:

  1. 插入数据必须移动其他数据,最坏情况下,就是插入到0位置,时间复杂度O(N);
  2. 删除数据必须移动其他数据,最坏情况下,就是删除0位置,时间复杂度O(N)
  3. 扩容之后有可能浪费空间(扩容之后结果我们只使用一两个空间)。

优点:

  1. 在给定下标情况下进行查找的时候,时间复杂度O(1);

        注意:顺序表适合给定下标查找的情况。

ps:本次内容就到这里了,如果对你有帮助的话,还请一键三连哦!!!

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

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

相关文章

前端量子纠缠 效果炸裂 multipleWindow3dScene

我 | 在这里 &#x1f575;️ 读书 | 长沙 ⭐软件工程 ⭐ 本科 &#x1f3e0; 工作 | 广州 ⭐ Java 全栈开发&#xff08;软件工程师&#xff09; &#x1f383; 爱好 | 研究技术、旅游、阅读、运动、喜欢流行歌曲 ✈️已经旅游的地点 | 新疆-乌鲁木齐、新疆-吐鲁番、广东-广州…

丽晶酒店及度假村打造绮丽之境“美食实验室”中国市场首秀

于重庆丽晶酒店以艺术与美食的碰撞演绎“对比之美”&#xff0c;感官之华 2023年11月28日&#xff0c;中国上海 ——基于对当下消费趋势的敏锐洞察&#xff0c;洲际酒店集团旗下奢华品牌丽晶酒店及度假村近年来不断焕新&#xff0c;以崭新形象缔造现代奢华的旅居体验。作为丽晶…

基于SSM的酒店预订管理系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

广州华锐互动:VR虚拟现实内容创作工具带来全新的应用场景

随着科技的不断发展&#xff0c;低代码编辑工具已经成为了一种越来越受欢迎的开发方式。它可以帮助开发人员快速构建应用程序&#xff0c;降低开发成本&#xff0c;提高开发效率&#xff0c;而VR虚拟现实内容创作工具带来了全新的应用场景。 VR虚拟现实内容创作工具是广州华锐互…

《数据结构、算法与应用C++语言描述》-线索二叉树的定义与C++实现

_23Threaded BinaryTree 可编译运行代码见&#xff1a;GIithub::Data-Structures-Algorithms-and-Applications/_24Threaded_BinaryTree 线索二叉树定义 在普通二叉树中&#xff0c;有很多nullptr指针被浪费了&#xff0c;可以将其利用起来。 首先我们要来看看这空指针有多少…

Webshell混淆免杀的一些思路

简介 为了避免被杀软检测到&#xff0c;黑客们会对Webshell进行混淆免杀。本文将介绍一些Webshell混淆免杀的思路&#xff0c;帮助安全人员更好地防范Webshell攻击。静态免杀是指通过对恶意软件进行混淆、加密或其他技术手段&#xff0c;使其在静态分析阶段难以被杀毒软件或安全…

linux 安装 mvn

mvn 下载地址&#xff1a;https://maven.apache.org/download.cgi 选择一个合适的版本 cd /opt && curl -o apache-maven-3.8.6-bin.tar.gz https://dlcdn.apache.org/maven/maven-3/3.8.6/binaries/apache-maven-3.8.6-bin.tar.gz tar -xzf apache-maven-3.8.6-bin.…

【EI会议投稿】第四届物联网与智慧城市国际学术会议(IoTSC 2024)

第四届物联网与智慧城市国际学术会议 2024 4th International Conference on Internet of Things and Smart City 继IoTSC前三届的成功举办&#xff0c;第四届物联网与智慧城市国际学术会议&#xff08;IoTSC 2024&#xff09;将于2024年3月22-24日在河南洛阳举办。 智慧城市的…

常见面试题-Redis 切片集群以及主节点选举机制

Redis 切片集群了解吗&#xff1f; 答&#xff1a; Redis 切片集群是目前使用比较多的方案&#xff0c;Redis 切面集群支持多个主从集群进行横向扩容&#xff0c;架构如下&#xff1a; 使用切片集群有什么好处&#xff1f; 提升 Redis 读写性能&#xff0c;之前的主从模式中&…

Python---lambda表达式

普通函数与匿名函数 在Python中&#xff0c;函数是一个被命名的、独立的完成特定功能的一段代码&#xff0c;并可能给调用它的程序一个返回值。 所以在Python中&#xff0c;函数大多数是有名函数 > 普通函数。但是有些情况下&#xff0c;我们为了简化程序代码&#xff0c;…

Android : Fragment 传递数据 — 简单应用

示例图&#xff1a; 创建 Fragment new -> Fragment -> Fragment&#xff08;Blank&#xff09; MainActivity.java package com.example.fragmentdemo;import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.FragmentManager; import andro…

00.本地搭建 threejs 文档网站(网页版是外网比较慢)

three官网 https://threejs.org/ 下载代码 进入官网 可以选择github去下载 或者 下载压缩包 github 下载https链接地址 https://github.com/mrdoob/three.js.git git clone https://github.com/mrdoob/three.js.git安装依赖启动程序 安装依赖 npm i 或者 pnpm i 或者 …