手把手教你如何实现List——ArrayList

目录

前言:

 线性表

顺序表

  接口的实现

一. 打印顺序表

二.新增元素,默认在数组最后新增

三.在 pos 位置新增元素 

四.判定是否包含某个元素

 五. 查找某个元素对应的位置

 六.获取 pos 位置的元素

七.给 pos 位置的元素设为 value 

八.删除第一次出现的关键字key 

九.获取顺序表长度

十.清空顺序表 

ArrayList的遍历

ArrayList的问题及思考

前言:

什么是List?

在集合框架中,List是一个接口,继承自Collection。

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

List中提供了好的方法,具体如下:

 

注意:List是个接口,并不能直接用来实例化。
如果要使用,必须去实例化List的实现类。在集合框架中,ArrayListLinkedList都实现了List接口。

本篇我们开始 ArrayList的学习


 线性表

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列...

线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。


顺序表

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

  接口的实现

先初始化数组 

有效数字现在为useSize 

模拟实现接口里面的所有的功能  也基本上就学会了顺序表的所有功能

实现在MyArrayList这个类中重写

一. 打印顺序表

 打印顺序表比较简单,知道它的userSize,遍历一遍就可以

public void display() {
        for (int i = 0; i < useSize ; i++) {
            System.out.print(elem[i] + "");
        }
        System.out.println();
    }

二.新增元素,默认在数组最后新增

思路: 直接找到userSize位置,直接赋值就行 有效数组userSize为4

假如我们需要添加5,直接在下标为4的位置上赋值

添加完userSize++

考虑问题要全,如果数组满了,我们需要给它扩容已被才可以添加 

所有得先判断是否数组满了,如果满了先扩容再添加

代码实现:

public void add(int data) {
        //判断
        if(useSize == 5) {
            elem = Arrays.copyOf(elem,elem.length*2);
        }
        //添加
        elem[useSize] = data;
        useSize++;
    }

 效果:


三.在 pos 位置新增元素 

 

在1下标添加11 

应该把1下标后面的元素往后面移动  从userSzie-1下标开始向右移动 

并且得先从最右边的元素开始移动

最后userSize++;

考虑情况:  

另外pos下标值不能小于0或者大于usersize

代码实现: 

 public void add(int pos, int data) {
        //先检查是否数组满了吗?
        if(useSize == 5) {
            elem = Arrays.copyOf(elem,elem.length*2);
        }
        // 判断pos是否合法
        if(pos < 0 || pos > useSize) {
            //抛出异常
            throw new PosException("pos未知不合法" + pos);
        }
        for (int i = useSize - 1; i >= pos ; i--) {
            elem[i+1] = elem[i];
        }
        elem[pos] = data;
        useSize++;
    }

 


四.判定是否包含某个元素

 

遍历整个数组,再判断

代码实现:  

   public boolean contains(int toFind) {
        for (int i = 0; i < useSize; i++) {
            if(elem[i] == toFind) {
                return true;
            }
        }
        return false;
    }

 五. 查找某个元素对应的位置

代码实现:  

   public int indexOf(int toFind) {
        for (int i = 0; i < useSize; i++) {
            if(elem[i] == toFind) {
                return i;
            }
        }
        return -1;
    }


 六.获取 pos 位置的元素

 

这里的pos不能等于userSize了,否则越界了 

代码实现:  

   public int get(int pos) {
         判断pos是否合法
        if(pos < 0 || pos >= useSize) {
            //抛出异常
            throw new PosException("pos未知不合法" + pos);
        }
        return elem[pos];
    }

七.给 pos 位置的元素设为 value 

代码实现:  

 public void set(int pos, int value) {
        // 判断pos是否合法
        if(pos < 0 || pos > useSize) {
            //抛出异常
            throw new PosException("pos未知不合法" + pos);
        }
        elem[pos] = value;
    }


八.删除第一次出现的关键字key 

 

先判断顺序表是否为空 空的不可以删除的

删除结束userSize-- 

 代码实现:  

    public void remove(int toRemove) {
        if(useSize == 0){
           throw new EmptyException("顺序表为空");
        }
        //获取toRemove下标
        int index = indexOf(toRemove);
        for (int i = index; i < useSize - 1 ; i++) {
            elem[i] = elem[i+1];
        }
        useSize--;
    }

九.获取顺序表长度

 public int size() {
        return useSize;
    }

十.清空顺序表 

 public void clear() {
        useSize = 0;
    }

 以上基本上就是顺序表所有的基本操作 


ArrayList的遍历

一:直接打印

 二:for循环遍历

三. for each遍历

 四.使用迭代器


ArrayList的问题及思考

1. ArrayList底层使用连续的空间,任意位置插入或删除元素时,需要将该位置后序元素整体往前或者往后搬移,故时间复杂度为O(N)
2. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。
3. 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。

当在ArrayList任意位置插入或者删除元素时,就需要将后序元素整体往前或者往后
搬移,时间复杂度为O(n),效率比较低,因此ArrayList不适合做任意位置插入和删除比较多的场景。

接下来我们会进行 LinkedList(链表)的学习

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

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

相关文章

Python中如何用栈实现队列

目录 一、引言 二、使用两个栈实现队列 三、性能分析 四、应用场景 五、代码示例 六、优缺点总结 一、引言 队列&#xff08;Queue&#xff09;和栈&#xff08;Stack&#xff09;是计算机科学中常用的数据结构。队列是一种特殊的线性表&#xff0c;只允许在表的前端进行…

HTTPS的介绍以及工作过程

目录 一.HTTPS是什么&#xff1f; HTTPS的介绍 HTTPS产生的背景 二.https的安全机制 加密是什么 如何加密 客户端如何获取公钥 总结 &#x1f381;个人主页&#xff1a;tq02的博客_CSDN博客-C语言,Java,Java数据结构领域博主 &#x1f3a5; 本文由 tq02 原创&#xff0…

OkHttp的配置

一、拦截器 1.添加拦截器的作用&#xff1a; 每次在请求过程中就会回调一次intercept方法 2.拦截器的回调方法里我们可以做那些事情&#xff1a; 当前的请求还没有发给服务器&#xff0c;比如我们在与服务器通信的时候&#xff0c;一个应用中很多地方都会跟服务器发起通信。…

Linux端口流量统计

Ubuntu sudo apt-get install wiresharkCentOS sudo yum install wiresharkUDP端口统计 sudo tshark -i <interface> -f "udp port <port_number>" -a duration:60 -q -z conv,udp请将 替换为你的网络接口&#xff0c;<port_number> 替换为要监…

ASP.NET Core 使用 SignalR 实现实时通讯

&#x1f433;简介 SignalR是一个用于ASP.NET的库&#xff0c;它允许服务器代码向连接的客户端实时发送推送通知。它使用WebSockets作为底层传输机制&#xff0c;但如果浏览器不支持WebSockets&#xff0c;它会自动回退到其他兼容的技术&#xff0c;如服务器发送事件&#xff…

Linux常用命令----shutdown命令

文章目录 命令概述参数解释使用示例及解释 命令概述 shutdown 命令用于安全地关闭或重启 Linux 系统。它允许管理员指定一个时间点执行操作&#xff0c;并可发送警告信息给所有登录的用户。 参数解释 时间参数 ([时间]): now: 立即执行关闭或重启操作。m: 在 m 分钟后执行操作…

centos7.9 + gitlab12.3.0安装

本文在centos7.9操作系统上安装gitlab 12.3.0&#xff0c;gitlab官方最新的版本已经是16.6.0了&#xff0c;这里仍然安装12.3.0版本的原因是汉化包的最新版本是12.3.0&#xff0c;如果汉化包的版本和gitlab的版本不对应&#xff0c;会出现汉化他无法启动的现象。 1、安装依赖 …

Web UI自动化测试框架

WebUI automation testing framework based on Selenium and unittest. 基于 selenium 和 unittest 的 Web UI自动化测试框架。 特点 提供更加简单API编写自动化测试。提供脚手架&#xff0c;快速生成自动化测试项目。自动生成HTML测试报告生成。自带断言方法&#xff0c;断言…

07-学成在线修改/查询课程的基本信息和营销信息

修改/查询单个课程信息 界面原型 第一步: 用户进入课程列表查询页面,点击编辑按钮编辑课程的相关信息 第二步: 进入编辑界面显示出当前编辑课程的信息,其中课程营销信息不是必填项,修改成功后会自动进入课程计划编辑页面 查询课程信息 请求/响应数据模型 使用Http Client测…

89基于matlab的人工蜂群和粒子群混合优化的路径规划算法

基于matlab的人工蜂群和粒子群混合优化的路径规划算法&#xff0c;起点和终点确定的前提下&#xff0c;在障碍物中寻找最佳路径。数据可更换自己的&#xff0c;程序已调通&#xff0c;可直接运行。 89人工蜂群和粒子群混合优化 (xiaohongshu.com)https://www.xiaohongshu.com/e…

【Vue】绝了!这生命周期流程真...

hello&#xff0c;我是小索奇&#xff0c;精心制作的Vue系列持续发放&#xff0c;涵盖大量的经验和示例&#xff0c;如果对您有用&#xff0c;可以点赞收藏哈~ 生命周期 Vue.js 组件生命周期&#xff1a; 生命周期函数&#xff08;钩子&#xff09;就是给我们提供了一些特定的…

Android flutter项目 启动优化实战(二)利用 App Startup 优化项目和使用flutterboost中的问题解决

背景 书接上回&#xff1a; Android flutter项目 启动优化实战&#xff08;一&#xff09;使用benchmark分析项目 已经分析出了问题: 1.缩短总时长&#xff08;解决黑屏问题、懒启动、优化流程&#xff09;、2.优化启动项&#xff08;使用App Startup&#xff09;、3.提升用…

java基础-IO

1、基础概念 1.1、文件(File) 文件的读写可以说是开发中必不可少的部分&#xff0c;因为系统会存在大量处理设备上的数据&#xff0c;这里的设备指硬盘&#xff0c;内存&#xff0c;键盘录入&#xff0c;网络传输等。当然这里需要考虑的问题不仅仅是实现&#xff0c;还包括同步…

【问题系列】消费者与MQ连接断开问题解决方案(一)

1. 问题描述 当使用RabbitMQ作为中间件&#xff0c;而消费者为服务时&#xff0c;可能会出现以下情况&#xff1a;在长时间没有消息传递后&#xff0c;消费者与RabbitMQ之间出现连接断开&#xff0c;导致无法处理新消息。解决这一问题的方法是重启Python消费者服务&#xff0c;…

redis运维(二十二)redis 的扩展应用 lua(四)

一 最佳实践 ① 铺垫 最佳实践&#xff1a;1、把redis操作所需的key通过KEYS进行参数传递2、其它的lua脚本所需的参数通过ARGV进行传递. redis lua脚本原理 Redis Lua脚本的执行原理 ② 删除指定的脚本缓存 ③ redis集群模式下使用lua脚本注意事项 1、常见报错现象 C…

草图大师sketchup道路怎么快速种树?

草图大师sketchup道路怎么快速种树&#xff1f;草图大师中的道路图纸想要在道路两旁种树&#xff0c;该怎么快速给道路种树呢&#xff1f;下面我们就来看看详细的教程&#xff0c;需要的朋友可以参考下 草图大师sketchup中想要快速种树&#xff0c;该怎么种多棵树呢&#xff1…

别太担心,人类只是把一小部分理性和感性放到了AI里

尽管人工智能&#xff08;AI&#xff09;在许多方面已经取得了重大进展&#xff0c;但它仍然无法完全复制人类的理性和感性。AI目前主要侧重于处理逻辑和分析任务&#xff0c;而人类则具有更复杂的思维能力和情感经验。 人类已经成功地将一些可以数据化和程序化的理性和感性特征…

JavaEE进阶学习:Bean 作用域和生命周期

1.Bean 作用域 .通过一个案例来看 Bean 作用域的问题 假设现在有一个公共的 Bean&#xff0c;提供给 A 用户和 B 用户使用&#xff0c;然而在使用的途中 A 用户却“悄悄”地修改了公共 Bean 的数据&#xff0c;导致 B 用户在使用时发生了预期之外的逻辑错误。 我们预期的结果…

leaflet对线设置渐变色

效果展示&#xff1a; 引用leaflet-polycolor组件 npm install leaflet-polycolor .vue文件中使用 import leafletPolycolor from leaflet-polycolor; leafletPolycolor(L); const latLngs [[37.03, 111.92], [37.53444, 111.98555], [36.88, 112.12], [37.53444, 112.24], […

Redis深入理解-主从架构下内核数据结构、主从同步以及主节点选举

Redis 主从挂载后的内核数据结构分析 主节点中&#xff0c;会通过 clusteNode 中的 slaves 来记录该主节点包含了哪些从节点&#xff0c;这个 slaves 是一个指向 *clusterNode[] 数组的数据结构从节点中&#xff0c;会通过 clusterNode 中的 slaveof 来记录该从节点属于哪个主…