ArrayList与顺序表(2)

 前言~🥳🎉🎉🎉  

hellohello~,大家好💕💕,这里是E绵绵呀✋✋ ,如果觉得这篇文章还不错的话还请点赞❤️❤️收藏💞 💞 关注💥💥,如果发现这篇文章有问题的话,欢迎各位评论留言指正,大家一起加油!一起chin up!👍👍 

💥个人主页:E绵绵的博客
💥所属专栏:JAVA知识点专栏   JAVA题目练习  c语言知识点专栏   c语言题目练习

在上一章我们将顺序表的模拟讲了之后,我们现在正式开始介绍ArrayList这个类(顺序表)。开始吧! 


参考文章:【Java 数据结构】顺序表_数据结构java顺序表基本算法测试-CSDN博客

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底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表


我们查看源码可知的确实施了这些接口。

这就是类定义的前部分,这里还是比较复杂的,会随着我们学习的深入,逐步学习到。

❤️❤️接下来我们来看ArrayList的几个成员变量:



对于第一个成员变量,我们无需了解,只需要关注下后面五个成员变量。

 使用ArrayList


 ArrayList的构造方法 


 第一个构造方法

当前是一个带参数的构造方法,很好理解,根据传递的参数开辟数组空间的大小。如果参数是等于0,就直接把 EMPTY_ELEMENTDATA 这个空数组赋值给存放数据的数组中。 如果是给定一个负数,显然是错误的,也即直接抛出异常!

第二个构造方法 


对于这个无参构造方法居然也是给了一个空数组,也就是没有分配数组内存,那它到底是怎么把数据放进去的?别急,随着后面的讲解,我们会解开这个谜题。

第三个构造方法 

 


里面涉及了泛型的进阶,我们这也不怎么好描述,就直接说特点吧:

下面是这个构造方法的一些特点:

参数c要求是实现了Collection接口的对象,

参数c中的<>元素类型必须与ArrayList中的<>元素类型兼容,即参数c中的<>元素类型必须是ArrayList中<>元素类型的子类或者相同类型。

在使用该构造方法后,它会按照参数c中元素的顺序将元素添加到新创建的ArrayList中。

实例如下:

public class Test {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("apple");
        list.add("banana");
        list.add("orange");

        ArrayList<String> arrayList = new ArrayList<>(list);
        System.out.println(arrayList);
    }

}


所以由这可知我们就将list内部的元素apple banana orange全部复制到Arraylist内部中(按顺序复制)。

ArrayList中的tostring方法 

由上图可知我们的ArrayList重写了toString方法。所以在用println时,内部参数为ArrayList对象时其将打印出该对象内部的所有元素,以字符串形式打印出来。

例如,如果ArrayList中有三个元素 “apple”、“banana” 和 “orange”,那么调用println方法将打印出字符串 “[apple, banana, orange]”。

ArrayList 的 add 方法 


别小看这几行代码,跟我们自己模拟实现的还是有区别的,真正有内涵的代码其实在 ensureCapacityInternal 这个方法中,那么现在,我们就一步步去解开他的面纱:

由这可知,我们就可以解开之前构造方法中的问题:我们用无参构造方法给其elementData一个空数组,也就是没有分配内存,那么它到底怎么存放数据进去?


我们看源码可知如果在使用add时elementData指向一个空数组,那么在使用add方法时内部的ensureCapacityInternal方法会给其element重新指向一个可以存放十个数据的数组,这样就可以存放数据了。


我们还从源码处可知在使用add时如果其数组中的数据已经满了,那么其会为该数组扩容1.5倍再存放数据。


所以这就是add的厉害之处。不仅能给内部为空数组的ArrayList对象重新开辟一个内部为10个数据的数组,使其能存放数据; 它还可以为满数据的数组实现扩容,使其也能存放数据。

 ArrayList的常用方法


在这里我们就重点讲两个方法 addAll和subList,

❤️❤️对于其他方法的使用,都很简单,自己去查源码,我这就不讲了。到了数据结构阶段,就要尝试着自己看源码,培养自主学习的能力!

 addAll方法

ArrayList中的addAll方法是用于将另一个集合c中的所有元素添加到当前ArrayList对象中的方法。它的语法如下:

boolean addAll(Collection<? extends E> c)

其中有以下要求:

参数c要求是实现了Collection接口的对象,

参数c中的<>元素类型必须与ArrayList中的<>元素类型兼容,即参数c中的<>元素类型必须是ArrayList中<>元素类型的子类或者相同类型。


这个方法可以用于批量添加元素到ArrayList对象中,方便快捷。注意,addAll方法不会去重,如果添加的元素在当前ArrayList中已经存在,则会重复添加

 subList方法

ArrayList中的subList方法用于获取原顺序表的一个子顺序表。它接受两个参数,分别是起始索引(fromindex)和结束索引(toindex),其左闭右开。一个新的List对象,包含原顺序表中指定范围内的元素。


subList方法返回的子顺序表在原顺序表的内部,对子顺序表的修改会反映到原顺序表上,反之亦然。这意味着,如果你修改了子顺序表中的元素,原顺序表也会相应地被修改;如果你修改了原顺序表中的元素,子顺序表也会相应地被修改。


需要注意的是,如果有一个顺序表此时存在一个子顺序表,现在将该顺序表结构性修改(如添加或删除元素),之后再用println打印子顺序表,会导致ConcurrentModificationException异常抛出。这是因为结构性修改改变了原顺序表的大小,从而也破坏了其子列表的大小,所以打印子列表时就报错。(内容牵涉到了迭代器,这里就不细讲)


ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);

List<Integer> subList = list.subList(1, 4);
System.out.println(subList);  // 输出:[2, 3, 4]

subList.set(0, 10);
System.out.println(list);  // 输出:[1, 10, 3, 4, 5]

list.add(6);
System.out.println(subList);  // 抛出ConcurrentModificationException异常

ArrayList的常用方法总使用 

 ❤️❤️以下是我们对常用方法的总使用,大家了解一下。

        ArrayList<Integer> arrayList = new ArrayList<>();
        // 1,插入(尾插)
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        arrayList.add(4);
        arrayList.add(5);
        System.out.println("插入数据后:" + arrayList);

        // 2,在任意位置插(下标)插入
        arrayList.add(0, -1);
        System.out.println("在0下标插入-1后:" + arrayList);

        // new 一个链表对象并尾插“1”,“2”
        LinkedList<Integer> linkedList = new LinkedList<>();
        linkedList.addLast(1);
        linkedList.addLast(2);
        // 3,插入 linklist 的所有元素
        arrayList.addAll(linkedList);
        System.out.println("插入linklist后:" + arrayList);

        // 4,删除任意位置(下标)数据
        arrayList.remove(0);
        System.out.println("删除0下标数据后:" + arrayList);

        // 5,删除指定数据
        arrayList.remove(new Integer(1));// 参数为Object(类)类型的对象
        System.out.println("删除第一个1后:" + arrayList);
        // 上面两个remove()方法构成了重载
        // remove()方法的参数如果输入整数之后不会自动装箱,而是会被自动识别为index。
        // 因为index是int类型,而顺序表中的数据是Object(类)类型
        // 但在插入数据时,输入的是1,基本类型,它会自动装箱,变成Integer类型
        //删除数据时之所以输入整数时不自动装箱是因为其参数本身就有index(整数)这个类型
        //所以优先选择该整型参数,不会自动装箱。
        // 所以要删除数据,应该输入类类型的对象,而不是基本类型的数据

        // 6,获取任意位置(下标)数据
        int ret = arrayList.get(0);
        System.out.println("得到0下标的数据:" + ret);

        // 7,更改任意位置(下标)数据
        arrayList.set(0,100);
        System.out.println("把0下标数据改成100后:" + arrayList);

        // 8,判断是否存在该数据
        boolean bl = arrayList.contains(100);
        System.out.println("判断是否存在100这个数据:" + bl);

        // 9,返回第一个key的位置(下标)
        int index = arrayList.indexOf(2);
        System.out.println("第一个2的下标:" + index);

        // 10,返回最后一个key的位置(下标)
        int lastIndex = arrayList.lastIndexOf(2);
        System.out.println("最后一个2的下标:" + lastIndex);

        // 11,获取顺序表长度
        int size = arrayList.size();
        System.out.println("顺序表长度为:" + size);

        // 12,截取
        List<Integer> list  = arrayList.subList(1, 3);
       // [1,3)左闭右开,返回出的子顺序表和ArrayList共用一个elementData数组

        System.out.println(list);

        // 13,清空顺序表
        arrayList.clear();
        System.out.println("清空顺序表后:" + arrayList);

ArrayList的遍历 

 ❤️❤️对于顺序表的遍历,我们可以通过 for 循环,for-each,以及迭代器的方法遍历:

public class TestArrayList {
    public static void main(String[] args) {
        ArrayList<Integer> arrayList = new ArrayList<>();
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        // 通过for循环遍历ArrayList
        for (int i = 0; i < arrayList.size(); i++) {
            System.out.print(arrayList.get(i) + " ");
        }
        // 通过for-each循环遍历ArrayList
        for (Integer integer : arrayList) {
            System.out.print(integer + " ");
        }
        // 通过迭代器遍历ArrayList(了解即可,无需深入了解,之后会学)
        Iterator<Integer> it = arrayList.iterator();
        while (it.hasNext()) {
            System.out.print(it.next() + " ");
        }
    }
}

除此以外,我们还可以通过println(ArrayList对象)打印出该对象内部的所有元素,这个方法我们在之前就讲过了,这里不多讲述了。

 总结

所以对于我们的顺序表的相关知识点就讲完啦,之后将给大家介绍链表,敬请期待! 还希望各位大佬们能给个三连,点点关注,点点赞,发发评论呀,感谢各位大佬~❤️❤️💕💕🥳🎉🎉🎉

 

 

 

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

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

相关文章

JavaScript中的map()方法详解

1. map() 的返回值是一个新的数组&#xff0c;新数组中的元素为 “原数组调用函数处理过后的值” 2. 简单使用&#xff1a;遍历整个数组&#xff0c;将大于4的元素乘以2 const array [2, 3, 4, 4, 5, 6]console.log("array",array) const map array.map(x > {…

nfs网络存储配置

准备&#xff1a;yum install rpcbind yum install nfs-server 一台服务器&#xff1a;192.168.220.131 一台客户端&#xff1a;192.168.220.220 服务器&#xff1a; 先启动rpcbind服务&#xff1a;systemctl restart rpcbind 在启动…

B站下行CDN架构的探索与应用

本期作者 背景介绍 B站的下行CDN旧架构如下图所示&#xff0c;可以看到边缘CDN节点与中心调度服务有紧密协作&#xff0c;简单说是先由调度服务进行流量调度(负责均衡的调度到每个网关组件节点&#xff09;&#xff0c;再由回源组件进行集群内的回源收敛&#xff0c;最终到对应…

Rust-01 Hello Rust 10分钟上手编写第一个Rust程序 背景介绍 发展历史 环境配置 升级打怪的必经之路

背景介绍 Rust 是一种多范式、通用的编程语言&#xff0c;强调性能、类型安全和并发性。它通过一个称为“借用检查器”的机制在编译时追踪所有引用的对象生命周期&#xff0c;以强制实现内存安全&#xff0c;即确保所有引用都指向有效的内存&#xff0c;而不需要垃圾收集器。 …

Qwen1.5微调

引子 由于工作上需要&#xff0c;一直在用Qwen做大模型推理&#xff0c;有个再训练的需求&#xff0c;特此琢磨下Qwen的训练。OK&#xff0c;我们开始吧。 一、安装环境 查看显卡驱动版本 根据官网推荐 OK&#xff0c;docker在手&#xff0c;天下我有。 docker pull qwenll…

白酒:馥郁香型白酒的香气特点与生产工艺

云仓酒庄的豪迈白酒介绍到&#xff0c;馥郁香型白酒以其与众不同的香气特点和杰出的生产工艺赢得了消费者的青睐。馥郁香型白酒以其香气浓郁、口感醇厚、回味悠长而著称。下面云仓酒庄豪迈白酒将深入探讨馥郁香型白酒的香气特点与生产工艺。 云仓酒庄豪迈白酒讲诉&#xff0c;馥…

go语言并发实战——日志收集系统(六) 编写日志收集系统客户端

上节回顾 在上一篇文章中我们介绍了编写客户端的四个步骤&#xff0c;分别是&#xff1a; 读取配置文件&#xff0c;寻找日志路径初始化服务根据日志路径l来收集日志将收集到的日志发送Kafka中 关于上述的内容博主画了一个思维导图(有点丑&#xff0c;大家勉强看看&#xff0…

flutter 设置启屏页 flutter_native_splash 坑记录

flutter_native_splash | Flutter packageCustomize Flutters default white native splash screen with background color and splash image. Supports dark mode, full screen, and more.https://pub.dev/packages/flutter_native_splash 发现一直白屏 原因是 代码中 下面…

关于Developers网站的一些使用分享

Android Developers 官网使用分享 语音切换android studio 版本下载最新版本下载位置历史版本下载位置 android studio 版本和 AGP 对应关系API 和 android studio 版本和 AGP 对应关系android studio 版本android 版本API levelandroid.hardware.camera2 语音切换 Developers…

要养生也要时尚,益百分满足你的所有需求

要养生也要时尚&#xff0c;益百分满足你的所有需求 艾灸是个好东西&#xff0c;尤其是在近几年的时候&#xff0c;艾灸就像一阵浪潮席卷进了人们的日常生活之中&#xff0c;我们可以在街边看到大大小小的艾灸馆&#xff0c;有些评价比较高的艾灸馆门前甚至还排起了长长的队伍…

在数字化转型过程中,企业的资产管理需要做出哪些调整?

在数字化转型过程中&#xff0c;企业的资产管理做出调整的常见于以下几个方面&#xff1a; 1、提高工作效率&#xff1a;数字化转型能够让员工在部门与部门之间的沟通更加顺畅&#xff0c;节省时间&#xff0c;提高效率。这要求企业在资产管理中采用数字化工具和流程&#xff…

《Chain-of-Thought Prompting Elicits Reasoning in Large Language Models》【大模型思维链】

目录 前言一、思维链介绍1-1、指令1-2、逻辑依据1-3、示例 二、Cot一般分类2-1、Zero-Shot-CoT2-2、Few-Shot-CoT 三、Cot的好处&缺陷&适用3-1、Cot的好处3-2、Cot的缺陷3-3、Cot的适用 四、变体4-1、自我验证&#xff08;self-consistency checking&#xff09; 总结 …

【剪映专业版】03立体自动翻页

【剪映专业版】立体自动翻页制作 1.导入素材&#xff0c;图片或视频均可 2.将素材2拖动至素材1的上方&#xff0c;点击蒙版&#xff0c;选择线性蒙版&#xff0c;并旋转为90度。 3.复制素材1&#xff0c;并拖动到素材2上方&#xff0c;分割并删除后半部分&#xff0c;点击蒙版…

WebGL绘制和变换三角形

1、绘制多个点 构建三维模型的基本单位是三角形。不管三维模型的形状多么复杂&#xff0c;其基本组成部分都是三角形&#xff0c;只不过复杂的模型由更多的三角形构成而已。 gl.vertexAttrib3f()一次只能向顶点着色器传入一个顶点&#xff0c;而绘制三角形、矩形和立方体等&am…

【MySQL 数据宝典】【磁盘结构】- 005 Undo log 撤销日志

一、基本介绍 ​ 每当我们要对一条记录做改动时&#xff08;这里的改动可以指 INSERT 、 DELETE 、 UPDATE &#xff09;&#xff0c;都需要留一手 -> 把回滚时所需的东西都给记下来 ​ 你插入一条记录时&#xff0c;至少要把这条记录的主键值记下来&#xff0c;之后回滚的…

【Redis】set 数据类型

文章目录 常用命令sadd & smemberssismember & scardspopsmove & srem 多个集合间的交互命令交集 & sinter & sinterstore并集 & sunion & sunionstore差集 & sdiff & sdiffstore 内部编码 集合类型也是保存多个字符串类型的元素的&#x…

【电控笔记5.6】Butterworth滤波器

Butterworth滤波器 需求&#xff1a;在增益交越频率拥有最小的相位滞后 波器经常被使用原因是 Butterworth 滤波器对于给定阶数&#xff0c;拥有最倾斜的衰减率而在伯德图又不会产生凸峰&#xff0c;同时在低频段的相位滞后小&#xff0c;因此本节将为各位介绍 Butterworth 低…

基于SSM的在线家教管理系统(含源码+sql+视频导入教程)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于SSM的在线家教管理系统1拥有三种角色 管理员&#xff1a;学生管理、老师管理、发布管理、留言管理、回复管理、订单管理等教师&#xff1a;我的订单、我的关注、查看回复留言、登录注…

使用 Docker 部署 Draw.io 在线流程图系统

1&#xff09;介绍 Draw.io GitHub&#xff1a;https://github.com/jgraph/drawio Draw.io 是一款开源的绘制流程图的工具&#xff0c;拥有大量免费素材和模板。程序本身支持中文在内的多国语言&#xff0c;创建的文档可以导出到多种网盘或本地。无论是创建流程图、组织结构图…

手拿滑块撕瑞数,我叫超弟你记住!腾讯滑块2024.4.23最新版,高复用,看到就是赚到,珍惜资源首次公开!!!

众所周知&#xff0c;腾讯阿里系安全属于国内天花板&#xff0c;让很多同行望眼欲穿&#xff0c;却束手无策&#xff0c;我们小团队因业务需要&#xff0c;一直都有现成的解决方案&#xff0c;有需求的朋友可以私信&#xff0c;后续准备办一个商学院&#xff0c;完全分享行内超…