ArrayList顺序表

news2024/12/24 10:26:07

目录

一、ArrayList变量的创建

二、ArrayList的三种构造方法

2.1 ArrayList() 

2.2 ArrayList(int)

2.3 ArrayList(Collection)

三、ArrayList常用方法介绍

3.1 boolean add(E e)

3.2 E remove(int index) 和 boolean remove(Object o)

3.3 List subList(int fromIndex, int toIndex)

3.4 常用的其他方法

四、ArrayList的遍历

4.1 for循环 + 下标

4.2 foreach循环

4.3 迭代器iterator

4.4 迭代器listIterator

4.5 迭代器listIterator倒着遍历

五、ArrayList的扩容机制

六、ArrayList的优缺点


一、ArrayList<E>变量的创建

二、ArrayList<E>的三种构造方法

2.1 ArrayList() 

如果在实例化ArrayList<E>对象时调用的是不带参数的构造方法则,编译器会默认让顺序表指向一个大小为0的Object[]常量数组。

2.2 ArrayList(int)

如果在实例化ArrayList<E>对象时调用的是参数为int的构造方法则,如果initialCapacity的值大于0,则实例化一个大小为initialCapacity大小的Object[]类型的数组,如果initialCapacity的值等于0,则编译器会让顺序表指向一个大小为0的常量Object[]数组,如果initialCapacity的值小于0,则会抛出异常。

2.3 ArrayList(Collection<? extends E>)

1. 在实例化ArrayList对象时可以给构造方法传引用数据类型的对象,但是对象的类型必须实现了Collection接口,且接口的<>里得是E或E的子类,其中E表示ArrayList中<>的泛型。

2. 下图中我们将arrayList对象作为参数传递给了ArrayList<E>的构造方法,为什么不报错,而将arrayList3对象作为参数传递给了ArrayList<E>的构造方法,为什么报错?

    答:不能将ArrayList<Integer>理解成Integer的子类,arrayList传入之所以符合是因为,它的类型ArrayList<Integer>,ArrayList实现了Collection接口,而<>中的Integer也是E的子类所以可以,如果把arrayList的类型修改成ArrayList<String>,String不是E的子类,在编译器中可以看到是不可以的。

三、ArrayList<E>常用方法介绍

3.1 boolean add(E e)

了解完ArrayLisr<E>的构造方法后,我们会发现在ArrayList<E>类中如果不明确指定顺序表的大小,则编译器在构造方法初始化顺序表时会让顺序表指向一个大小为0的Object[]类型的数组,如果我们直接在实例化ArrayList<E>对象后,使用对象的引用调用add方法,会发现编译器并没有报错,可是顺序表的大小不是0吗,我们也没看到扩容操作啊,为什么不报错呢?

答:如下图所示,我们观察到add方法内部的代码,发现在给顺序表有效数据后插入新的数据前,会先判断顺序表的大小和有效数组个数size的大小是否相等,如果相等,表示需要先对顺序表进行扩容操作,具体的扩容细节见下图所示,如果是因为顺序表本身就没开辟空间,则会将顺序表的大小设置成10,如果是因为顺序表已满,则将顺序表按照原本大小的1.5被扩容。总之,之所以没报错的原因是,add方法里存在扩容代码。

 

3.2 E remove(int index) 和 boolean remove(Object o)

E remove(int index) :删除 index 位置元素

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

【注意】:在给remove方法传参时,如果传递的是整型,编译器只会把它认为是下标,而不会认为是你想删除顺序表中第一次出现的元素10,如果想达到删除顺序表中第一次出现的元素10,得先将10装箱,示例代码:arrayList.remove(Integer.valueOf(10))

3.3 List subList(int fromIndex, int toIndex)

List<E> subList(int fromIndex, int toIndex):截取部分 list,仍然是左闭右开(注意一下该方法的返回值为List<E>,别写成其他的了)。

【注意】:使用subList截取的结果并不是重新new了一个数组存放的截取部分,而是返回了顺序表中下标为formLindex元素的地址。如果我们修改了截取部分数组中的元素的值,顺序表中的对应部分元素的值也会同时发生改变。

3.4 常用的其他方法

注意一下:remove(int)的返回值为被移除的元素。

public static void main(String[] args) {
        ArrayList<Integer> arrayList = new ArrayList<>();
        arrayList.add(100);//在表尾插入元素
        arrayList.add(101);
        arrayList.add(102);
        System.out.println(arrayList);//[100, 101, 102]

        arrayList.add(1,200);//在指定下标处插入元素
        System.out.println(arrayList);//[100, 200, 101, 102]
        arrayList.add(2,300);
        System.out.println(arrayList);//[100, 200, 300, 101, 102]

        ArrayList<Integer> cur = new ArrayList<>();
        cur.add(999);
        cur.add(888);
        cur.add(999);
        arrayList.addAll(cur);//在表尾插入另一个顺序表
        System.out.println(arrayList);//[100, 200, 300, 101, 102, 999, 888, 999]

        arrayList.remove(1);//删除指定下标的元素
        System.out.println(arrayList);//[100, 300, 101, 102, 999, 888, 999]
        arrayList.remove(2);
        System.out.println(arrayList);//[100, 300, 102, 999, 888, 999]

        arrayList.remove(Integer.valueOf(999));//删除第一次出现的999
        System.out.println(arrayList);//[100, 300, 102, 888, 999]

        Integer a = arrayList.get(1);//得到某下标的元素

        arrayList.set(1,777);//把某下标的元素置为777
        System.out.println(arrayList);//[100, 777, 102, 888, 999]
        //arrayList.set(100,777);//越界异常

        boolean b = arrayList.contains(777);//是否包含某元素
        System.out.println(b);//true

        arrayList.add(777);
        System.out.println(arrayList);//[100, 777, 102, 888, 999, 777]

        int c = arrayList.indexOf(777);//某元素第一次出现的下标
        System.out.println(c);//1

        int d = arrayList.lastIndexOf(777);//从后往前找,某元素第一次出现的位置
        System.out.println(d);//5

        List<Integer> e = arrayList.subList(1,3);//
        System.out.println(e);//[777, 102]
        e.set(0,33333);
        System.out.println(arrayList);//[100, 33333, 102, 888, 999, 777]
        System.out.println(e);//[33333, 102]

        arrayList.clear();
        System.out.println(arrayList);//[]
}

四、ArrayList<E>的遍历

下面将提供5种遍历方式,使用下标遍历的好处是可以通过下标去修改顺序表中元素的值,其他4中方式仅能得到每个元素的值,不能够修改。

4.1 for循环 + 下标

4.2 foreach循环

4.3 迭代器iterator

【书写格式】:Iterator<xxx> name = 顺序表.iterator(); 然后通过while循环,循环的条件是name.hasNext(),来判断是否有下一个元素,取元素的值时用name.next()取即可。

【解惑】:之所以arrayList对象可以调用iterator方法是因为,ArrayList<E>实现了Iterable<T>接口,Iterable<T>接口中有抽象方法iterator,而ArrayList<E>中重写了iterator方法。

下图是ArrayList<E>中重写的iterator方法,可以发现它的返回类型是Iterator<E>,调用该方法后,接收返回值的时候要注意一下,要写成Iterator<E>类型的:

下图是Iterable<T>接口,可以看到它有抽象方法iterator:

4.4 迭代器listIterator

【书写格式】:Iterator<xxx> name = 顺序表.listIterator();

                     或 ListIterator<xxx> name = 顺序表.listIterator();

然后通过while循环,循环的条件是name.hasNext(),来判断是否有下一个元素,取元素的值时用name.next()取即可。

【注意】ListIterator<E> 是 Iterator<E>的子类,所以可以写成书写格式一的样子。

               之所以arrayList对象可以调用listIterator方法是因为ArrayList类里面实现了这个该方法了的,不过通过观察ListIterator接口的源码可以发现它里面并没有listIterator方法,所以初步断定ArrayList并不是重写了ListIterator接口中的listIterator方法,而是它自己的listIterator方法。

4.5 迭代器listIterator倒着遍历

【说明】:listIterator方法可以整型,而iterator方法是不可以传参的。如果给listIterator方法传整型则可以倒叙遍历顺序表,不过开始的书写格式必须写成, ListIterator<xxx> name = 顺序表.listIterator(); 不能写成Iterator<xxx> name = 顺序表.listIterator(); 因为Iterator<E>没有hasPrevious、previous方法。

五、ArrayList<E>的扩容机制

该扩容机制在上文的add方法中就已经讲解得差不多了,这里主要想强调的是:

① ArrayList是一个动态类型的顺序表,即:在插入元素的过程中会自动扩容。

② 扩容时调用的时grow方法。

③ 使用Arrays.copyOf(数组,新的数组大小)进行具体的扩容。

④ ArrayList<E>的扩容方法被封装了,我们无法通过ArrayList<E>对象的引用调用对应的扩容方法,它底层的扩容逻辑是按原数组的1.5倍进行扩容的。

六、ArrayList的优缺点

1. 优点:ArrayList底层使用连续的空间,在访问某一具体的元素时所用的时间复杂度为O(1)

2. 缺点:

         ① ArrayList底层使用连续的空间,任意位置插入或删除元素时,需要将该位置后序元素整体往前或者往后搬移,故时间复杂度为O(N)。

         ② 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。增容一般是呈2或1.5倍的增长,势必会有一定的空间浪费,例如当前容量为100,满了以后增容到200,我们再继 续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。

3. 针对ArrayList的缺点于是引入了链表的概念,不过链表的优缺点 其实就是 顺序表的缺优点

 本篇已完结 ......

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

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

相关文章

hive udtf 函数:输入一个字符串,将这个字符串按照特殊的逻辑处理之后,输出4个字段

这里要继承GenericUDTF 这个抽象类,直接上代码: package com.xxx.hive.udf; import org.apache.commons.lang.StringUtils; import org.apache.hadoop.hive.ql.exec.Description; import org.apache.hadoop.hive.ql.exec.UDFArgumentException; import org.apache.hadoop.hi…

2024年最建议买哪几款蓝牙耳机?四大2024性价比王牌机型推荐

随着科技的飞速发展&#xff0c;蓝牙耳机已经从昔日的奢侈品转变为如今生活中的必需品。面对日益丰富的产品线和不断更新的技术特性&#xff0c;选择一款适合自己的蓝牙耳机变得越来越具有挑战性&#xff0c;那么在2024年最建议买哪几款蓝牙耳机&#xff1f;作为蓝牙耳机爱好者…

48天笔试训练错题——day42

目录 选择题 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 编程题 1. 走迷宫 选择题 1. 动态分配&#xff1a;使用 DHCP 协议动态分配 IP。 IP 地址不但有单播地址&#xff0c;多播地址&#xff0c;还有广播地址。 如果一个主机有块个网卡&#xff0c;那么每块网卡都可以拥…

人工智能时代,程序员如何保持核心竞争力,不会一觉醒来,被自己写的代码淘汰了 ≧ ﹏ ≦

随着AIGC&#xff08;人工智能生成内容&#xff09;技术的飞速发展&#xff0c;尤其是像ChatGPT、Midjourney、Claude等大语言模型的崛起&#xff0c;人工智能正以前所未有的速度渗透到编程领域&#xff0c;彻底改变了程序员的工作方式。这一变革既带来了挑战&#xff0c;也孕育…

2024/08 近期关于AI的阅读和理解[笔记]

#Cohere 就像商业能力很强的云数仓公司 Snowflake 一样&#xff0c;Cohere 也采用了按需付费模式而不是按月或按年付费&#xff0c;而且它的付费模式很精细。Cohere 按照模型的不同能力&#xff0c;包括文本生成&#xff0c;文本总结&#xff0c;重新排名&#xff0c;文本分类…

pikachu文件下载

一&#xff1a;简介 在许多 web 系统中都有文件下载功能&#xff0c;点击下载链接会向后台发送含文件名的下载请求&#xff0c;后台收到后执行下载代码将对应文件返回给浏览器完成下载。若后台收到文件名后直接拼进下载路径而不做安全判断&#xff0c;可能引发不安全的文件下载…

【楚怡杯】职业院校技能大赛 “Python程序开发”赛项样题四

一、竞赛任务概述 本赛项包括“网络爬虫”、“数据清洗”、“数据分析与可视化”、“机器学习”4个竞赛任务&#xff0c;各任务分值分别为15分、30分、35分、20分&#xff0c;本赛项满分为100分。 二、注意事项 1.请根据大赛所提供的竞赛环境&#xff0c;检查所列的硬件设备…

2024最新版Python基础入门学习路线

Python基础入门学习路线可以概括为以下几个阶段&#xff0c;每个阶段都包含了关键的学习内容和目标&#xff1a; 一、Python语言基础 1. 初识Python语言 Python语言概述&#xff1a;了解Python的起源、特点、应用领域以及发展趋势。环境安装&#xff1a;学习如何在不同的操作系…

Web API 渗透测试指南

概述 API&#xff08;Application Programming Interface&#xff0c;应用程序编程接口&#xff09;是一个允许不同软件应用程序之间进行通信和数据交换的接口。API定义了一组规则和协议&#xff0c;软件开发者可以使用这些规则和协议来访问操作系统、库、服务或其他应用程序的…

【HarmonyOS NEXT星河版开发学习】小型测试案例02-华为登录

个人主页→VON 收录专栏→鸿蒙开发小型案例总结​​​​​ 基础语法部分会发布于github 和 gitee上面&#xff08;还未发布&#xff09; 前言 通过此案例&#xff0c;不得不感叹鸿蒙的强大了&#xff0c;仅仅使用了26行代码就构建出来了这个界面&#xff0c;确实特别方便&#…

k8s-service暴露pod

service暴露pod----nginx 1.编写nginx-deployment.yaml文件 [rootk8s-master deployment]# vim nginx-deployment.yaml [rootk8s-master deployment]# cat nginx-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: deployment namespace: default s…

二进制部署Mysql8.0.31

一、软件包下载 企业版&#xff1a;Enterprise , 互联网行业一般不选择.社区版本&#xff1a;选择源码包 编译安装&#xff1a; source code .tar.gz 通用二进制 公司用什么版本数据库? 具体什么小版本号? 5.6.20 5.6.34 5.6.36 5.6.38 5.6.40 5.7.18 5.7.20 5…

【初阶数据结构】详解顺序表(上)

文章目录 1. 数据结构2. 顺序表2.1 顺序表的概念及结构2.1.1 线性表2.1.2 顺序表与数组的差别 2.2 顺序表的分类2.2.1 静态顺序表2.2.2 动态顺序表 2.3 静态顺序表和动态顺序表的区别 在学完C语言的知识后&#xff0c;我们也该跨入到学习数据结构的领域中来。毕竟学习语法是为解…

带风扇工业电脑行业分析:预计2030年全球市场规模将达到45.8亿美元

工业电脑是用于工业用途&#xff08;生产产品和服务&#xff09;的计算机&#xff0c;其外形尺寸介于上网本和服务器机架之间。工业电脑的可靠性和精度标准更高&#xff0c;价格通常比消费电子产品更昂贵。它们通常使用复杂的指令集&#xff0c;例如 x86&#xff0c;而其他指令…

用的到linux-tomcat端口占用排查-Day5

前言&#xff1a; 最近使用tomcat搭建了一套测试环境的应用&#xff0c;整个搭建过程也很简单&#xff0c;就是将部署包上传至服务器☞解压☞启动tomcat服务器&#xff0c;当然服务器也是成功启动了&#xff0c;但是发现前端应用报404&#xff0c;具体如下图所示。 一、现象及思…

新手买智能猫砂盆怎样不踩雷?三大热门款测评推荐!

上班族养猫最害怕的就是&#xff0c;辛苦一天回到家&#xff0c;发现家里弥漫着猫便便的味道和满盆的猫屎&#xff0c;满地的猫砂&#xff0c;就感觉整个人都绝望了&#xff0c;你们现在是不是这样&#xff1f;以前的我真是为了解决这个问题想破了脑袋&#xff0c;后面才了解到…

电话营销机器人革新电销行业

第一&#xff0c;减少企业各方面的支出 企业需要各方面的支出。例如&#xff0c;招聘成本和管理成本、员工薪资和社保都是非常大的支出。但AI智能电销机器人&#xff0c;只要购买费用和电话费的一小部分&#xff0c;就没有更多的费用。经计算&#xff0c;该机器人的成本仅相当于…

java之静态内部类

1.什么是静态内部类 答:静态内部类是一种特殊的成员内部类 2.直接创建静态内部类对象的方式? Outer.Inner oinew Outer.Inner(); public class Outer {int a10;static int b20;static class Inner{public void show1(){System.out.println("非静态里的方法被调用了&qu…

【Qt】探索Qt网络编程:构建高效通信应用

文章目录 前言&#xff1a;1. Qt 网络编程介绍1.1 什么是网络编程&#xff1f;1.2 Qt的模块 2. UDP Socket2.1 核心 API 概述2.2 写一个带有界面的 Udp 回显服务器2.3 写一个带有界面的 Udp 客户端 3. TCP Socket3.1 核心 API 概述3.2 代码&#xff1a; 4. HTTP Client4.1 核心…

基于InP的通用光子集成技术(五)

Meint Smit et al 2014 Semicond. Sci. Technol. 29 083001 9.通用测试 9.1. 晶圆验证 在通用工艺中&#xff0c;必须对每批次晶片的工艺性能进行验证&#xff1b;客户将期待这样的验证。在MPW中&#xff0c;验证用户ASPIC工艺性能是不实际的&#xff1b;每个ASPIC都需要不同的…