手敲myarraylist,深入了解其运行逻辑

news2024/11/17 9:29:43

1、自定义MyArrayList类

        该类里面基本有两个属性,一个是用来存放数据的数组,另外一个是用来描述已经存放数据的数量。同时设置arraylist表的默认长度为10;代码如下:

public class MyArrayList {
    private int[] elem;
    private int usedSize;//表示表的实际占用空间

    //顺序表的默认大小
    public static final int DEFAULT_SIZE = 10;
    public MyArrayList(int[] elem) {
        elem = new  int[DEFAULT_SIZE];
    }
}

2. 创建接口

        我们创建一个接口,要将arraylist要实现的抽象方法列出来,使得后期直接在自定义类里面能够具体化;

public interface IList {
    //新增元素,默认在数组最后新增
    public void add(int data);
    // 在 pos 位置新增元素
    public void add(int pos, int data);
    // 判定是否包含某个元素
    public boolean contains(int toFind) ;
    // 查找某个元素对应的位置
    public int indexOf(int toFind);
    // 获取 pos 位置的元素
    public int get(int pos);
    // 给 pos 位置的元素设为 value  更新
    public void set(int pos, int value);
    //删除第一次出现的关键字key
    public void remove(int toRemove) ;
    // 获取顺序表长度
    public int size();
    // 清空顺序表
    public void clear() ;
    // 打印顺序表,注意:该方法并不是顺序表中的方法,为了方便看测试结果给出的
    public void display();

    boolean isFull();

    public boolean isEmpty();
}

0594d631c9c64646954505e845c8119c.png

        同时我们的自定义类实现该接口,并实现接口中的方法;我们接下来通过自己手敲arraylist的一些方法来从底层深入的学习arraylist表如何完成一系列的方法实现,方便我们了解arraylist表的运行逻辑和优缺点;

3、实现具体方法

3.1 打印顺序表

        只要知道当前类对象的实际长度即可完成打印顺序表操作;

 @Override
    public void display() {
        for (int i = 0; i <= this.usedSize-1; i++) {
            System.out.print(this.elem[i]+"->");
        }
        System.out.println();
    }

3.2新增元素 

        我们此处的方法默认添加的每一个元素是从底层数组末尾依次添加的

        思路:

        1、 首先需要确定当前存储在数组中最后一位数据的索引(即usedSize-1),然后下一个存储空间范围合法的话,直接将我们要添加的数据放到接下来的数组索引上即可(数据存放的索引应该为usedSized)

        1.1 这时候就要考虑如果我们要存放数据之前要判断数组的空间是否满了(我们之前默认存储容量为10);

        1.2 如果判断出数组当前已满,我们就要对数组存空容量进行扩容;

        2、添加完成后,usedSize往后移一位;

7465cf75839643acbc1888171cc5a1c5.png

        代码如下 

@Override
    public void add(int data) {
        checkCapacity();
        //此时表示空间足够,可以存放数据
        this.elem[this.usedSize] = data;
        this.usedSize++;
    }

    private void checkCapacity() {
        if (isFull()){
            //如果当前的数组已经满了,我们就要扩容
            elem = Arrays.copyOf(elem,elem.length*2);
        }
    }
 
@Override
    public boolean isFull() {
        return usedSize == elem.length;
    }

        测试及结果:

public static void main(String[] args) {
        MyArrayList myArrayList = new MyArrayList();
        myArrayList.add(2023);
        myArrayList.add(11);
        myArrayList.add(29);
        myArrayList.display();
    }

1fd0a62fd02845bab7343a880cb9fb31.png

3.3 在 pos 位置新增元素 

        思路:在pos下标添加data;

        1、应该把pos下标到usedSzie-1下标之间的元素往右面移动(包含pos),且得先从最右边的元素开始移动

        1、1必须保证pos下标位置在0~usedSize范围之间;(即一个顺序表只有0下标有位置,想要往3下标位置插入数据是不科学的)

        1.2 如果要在usedSize-1的位置插入数据,我们要进行扩容操作;

        2、最后userSize++;

        详细图解如下图所示:

c844f578a866406292dab11fde630f15.png

        代码如下所示:

public class PosIllegality extends RuntimeException{
    public PosIllegality(String msg){
        super(msg);
    }
}

 @Override
    public void add(int pos, int data) {
        try {
            checkPosOnAdd(pos);
        }catch (PosIllegality e) {
            e.printStackTrace();
            return;
        }
        //必须保证pos下标位置在0~usedSize范围之间,所以要检查
        checkCapacity();
        //1、从最后一个有效的数据开始往后移动
        // 2、当i < pos 就结束
        for (int i = usedSize-1; i >= pos; i--) {
            //下标为pos的也得搬家
            elem[i+1] = elem[i];
        }
        //3、存放元素到pos 位置
        elem[pos] = data;
        //4、usedSize++;
        usedSize++;
    }
 checkCapacity();
        //1、从最后一个有效的数据开始往后移动 //2、当i < pos 就结束
        for (int i = usedSize-1; i >= pos; i--) {
            elem[i+1] = elem[i];
        }
        //3、存放元素到pos 位置
        elem[pos] = data;
        //4、usedSize++;
        usedSize++;
    }

        执行结果:

        eg1:

public static void main(String[] args) {
        MyArrayList myArrayList = new MyArrayList();
        myArrayList.add(2023);
        myArrayList.add(11);
        myArrayList.add(29);
        myArrayList.add(4,99);
        myArrayList.display();
    }

1263c13a2de348febc0c2c1ec1093880.png

        eg2:

public static void main(String[] args) {
        MyArrayList myArrayList = new MyArrayList();
        myArrayList.add(2023);
        myArrayList.add(11);
        myArrayList.add(29);
        myArrayList.add(2,29);
        myArrayList.display();
    }

aa13e3e5a5e8420d99b713d8a34119e1.png

3.4判定是否包含某个元素

        思路:先遍历整个数组,再判断是否包含;

        注意:首先要判断列表是否为空

        此处代码图解:

87077505fd8c48e28113f60bf3f86e84.png

 @Override
    public boolean contains(int toFind) {
        if(isEmpty()) {
            return false;
        }
        for (int i = 0; i < usedSize; i++) {
            //如果是查找引用数据类型 一定记住 重写方法
            if(elem[i] == toFind) {
                return true;
            }
        }
        return false;
    }

 @Override
    public boolean isEmpty() {
        return usedSize == 0;
    }

3.5 查找某个元素对应的位置 

        找到列表中的钙元素,返回其在列表中的索引

        思路:

        1、如果列表为空,则返回-1;

        2、遍历数组,找到返回索引,找不到返回-1;

        下图为方法代码和运行结果

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

public static void main(String[] args) {
        MyArrayList myArrayList = new MyArrayList();
        myArrayList.add(2023);
        myArrayList.add(11);
        myArrayList.add(29);
        myArrayList.add(2,29);
        myArrayList.display();
        System.out.println(myArrayList.indexOf(2023));
        System.out.println(myArrayList.indexOf(2024));
    }

4d77f1b410e441ecad471c560691e604.png

3.6 获取 pos 位置的元素

        思路:

        1、检查pos是否合法,当pos不合法时,抛出异常,停止下面的代码运行;

        2、检查书序表是否为空,如果链表为空,抛出异常,停止下面的代码运行;

        3、除此外,返回pos 位置的元素

        下图为代码逻辑图:

9b14bb7d431a4b9cad28a2a993bfb945.png

        具体方法如下:

public class MyArrayListEmpty extends RuntimeException{
    public MyArrayListEmpty(String msg){
        super(msg);
    }
}

@Override
    public int get(int pos) {
        checkPosOnGetAndSet(pos);
        if (isEmpty()){
            throw new MyArrayListEmpty("获取指定下标元素时" +
                    "顺序表为空!");
        }
        return elem[pos];
    }
private void checkPosOnGetAndSet(int pos) {
        if (pos < 0 || pos > usedSize){
            System.out.println("这个pos不符合法!");
            throw new PosIllegality("查找pos下标元素时发现pos异常: "+pos);
        }
    }

        执行代码及结果:

 public static void main(String[] args) {
        MyArrayList myArrayList = new MyArrayList();
        myArrayList.add(2023);
        myArrayList.add(11);
        myArrayList.add(29);
        myArrayList.add(2,29);
        myArrayList.display();
        System.out.println(myArrayList.get(1));
        System.out.println(myArrayList.get(6));
    }

ebc497c0932547a7afd012b12dc0f291.png3.7 给 pos 位置的元素设为 value 

        代码如下:

 @Override
    public void set(int pos, int value) {
        checkPosOnGetAndSet(pos);

        elem[pos] = value;
    }
public static void main(String[] args) {
        MyArrayList myArrayList = new MyArrayList();
        myArrayList.add(2023);
        myArrayList.add(11);
        myArrayList.add(29);
        myArrayList.add(2,29);
        myArrayList.display();
        myArrayList.set(1,2029);
       myArrayList.display();
    }

        运行结果如图所示: 

d30410b7a19248cfb4a2a193d59a971d.png

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

        思路:

         1、先通过查找索引的方法,寻找key在列表中的索引。如果没有找到,停止运行

        2、如果找到,开始删除该元素,自这个元素以后得所有元素往前移一个单位

        3、删除成功后,usedSize--                 

@Override
    public void remove(int toRemove) {
        int index = indexOf(toRemove);
        if(index == -1) {
            System.out.println("没有这个数字!");
            return;
        }
        for(int i = index; i < usedSize-1;i++) {
            elem[i] = elem[i+1];
        }
        usedSize--;
    }

3.9 获取顺序表长度 

@Override
    public int size() {
        return this.usedSize;
    }

3.10 清空顺序表 

 @Override
    public void clear() {
        this.usedSize = 0;
    }

ps:本次内容就到这里结束了,喜欢的话,还请大家一键三连哦!!! 

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

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

相关文章

基于matlab的图像去噪算法设计与实现

摘 要 随着我们生活水平的提高&#xff0c;科技产品飞速更新换代&#xff0c;在信息传输中&#xff0c;图像传输所占的比重越来越大。但自然噪声会在图像传输时干扰其传输过程&#xff0c;甚至会使图片不能表达其原来的意义。去噪处理就是为了去除图像中的噪声&#xff0c;从而…

出口贸易媒体发稿7种方法提升转化率的秘密武器解析-华媒舍

出口贸易成为了许多企业发展的重要方向。在这个竞争激烈的市场中&#xff0c;如何让自己的产品脱颖而出&#xff0c;吸引更多客户并提高转化率&#xff0c;成为了每个企业家都面临的挑战。本文将向大家介绍7种提升转化率的秘密武器&#xff1a;出口贸易媒体发稿方法。 1. 出口贸…

如何获取1688的订单详情

获取1688订单详情需要申请 第一步&#xff1a;先去1688-开放平台申请&#xff0c;申请不一定能通过&#xff0c;审批很严。 第二步&#xff1a;首次登录请先注册&#xff0c;注册成功后即可登录。 第三步&#xff1a;选择&#xff1a;我是第三方开发者 第三方是封装好的ap…

如何判断数据库慢 SQL 查询?

慢 SQL 查询通常指执行时间较长或者消耗大量系统资源的查询。要判断一个 SQL 查询是否慢&#xff0c;可以考虑以下几个方面&#xff1a; 执行时间&#xff1a; 观察查询执行所需的时间。如果一个查询花费了相对较长的时间才能返回结果&#xff0c;可能就是慢查询的一个指标。通…

JavaScript黑科技:简洁有用的一行代码,让你的开发效率飙升!

说在前面 在这篇技术博客中&#xff0c;我们将向你介绍一些令人惊叹的JavaScript黑科技&#xff0c;这些只需一行代码就能实现的简洁而有用的功能&#xff0c;将极大地提升你的开发效率。无论是优化代码、增加交互性&#xff0c;还是实现复杂的逻辑&#xff0c;这些代码片段将成…

【教程】 一文部署配置并入门 Redis

综述 什么是Redis Redis官网——Redis.io Redis, 作为一个高性能的键值对数据库&#xff0c;主要应用于以下场景&#xff1a; 缓存系统&#xff1a;由于其高速读写能力&#xff0c;Redis 非常适合用作缓存系统&#xff0c;减少数据库负载。 会话存储&#xff08;Session St…

c++基本常见错误总结

我们无论是在学习中还是在工作当中&#xff0c;总是会遇到各种各样的c编译错误问题&#xff0c;经常会有一种情况就是上一次好像遇到过这种问题&#xff0c;但是就是想不起来了&#xff08;我就是这样&#xff09;所以下面这一篇文章就是总结自己遇到的编译以及运行错误。 注意…

Javase | Java常用类 (不断补充中...)

目录: 1.Object类2.String类3.StringBuffer类4.Math类5.Random类6.包装类(不断补充中...) 1.Object类 Object类是Java语言中的所有类的超类&#xff0c;即所有类的根。它中描述的所有方法&#xff0c;所有类都可以使用。 equals( ) : 指示其他某个对象与此对象“是否相等” (比…

SD-WAN是否将终结IPsec VPN?

在网络架构的演进历程中&#xff0c;IPsec VPN一直扮演着至关重要的技术角色。而近年来备受关注的SD-WAN技术日益成熟&#xff0c;各大服务供应商纷纷将其与IPsec VPN进行对比&#xff0c;似乎预示着SD-WAN必然替代传统的IPsec VPN。 然而事实究竟如何&#xff1f;SD-WAN等于IP…

Vue项目解决van-calendar 显示白色空白,需滑动一下屏幕,才可正常显示

问题描述&#xff0c;如图 ipad(平板&#xff09;或者 H5移动端引入Vant组件的日历组件&#xff08;van-calendar&#xff09;&#xff0c;初始化显示空白&#xff0c;需滚动一下屏幕&#xff0c;才可正常显示 解决方法 需在van-calendar上绑定open"openCalendar"事件…

AI堆栈之战正在升温

原创 | 文 BFT机器人 从OpenAI和微软最近的现状可以看出&#xff0c;争夺更多新兴AI堆栈的竞争正在加剧。AI堆栈是用于开发和部署AI应用程序的技术、框架和工具的集合&#xff0c;通常包括多个层或组件。 在微软Ignite会议和OpenAI首届DevDay大会的背景下&#xff0c;一些行业…

福德植保无人机:农业科技的新篇章

一、引言随着科技的不断发展&#xff0c;无人机技术在许多领域中都得到了广泛的应用。近年来&#xff0c;福德植保无人机在农业领域大放异彩&#xff0c;成为了现代化农业的重要一环。本篇文章将为您详细介绍福德植保无人机的优势、特点以及未来发展趋势。 二、福德植保无人机的…

分油问题C++求解

原题 3个油桶&#xff0c;容量分别为&#xff08;大桶&#xff09;20&#xff0c;&#xff08;中桶&#xff09;9&#xff0c;&#xff08;小桶&#xff09;7&#xff0c;初始时大桶满油&#xff0c;如何操作可以分出17的油&#xff1f; 代码 #include<iostream> #inc…

Unity中Shader编译目标级别

文章目录 前言一、Shader Model二、Shader编译目标级别法1&#xff1a; #pragma target 3.0法2&#xff1a;#pragma require integers geometry 三、测试代码 前言 针对不同平台的特性&#xff0c;所做的一些功能 一、Shader Model ShaderModel 由微软提出&#xff0c;要求显…

【LeetCode】栈和队列OJ题---C语言版

栈和队列OJ题 1.括号匹配问题&#xff08;1&#xff09;题目描述&#xff1a;&#xff08;2&#xff09;思路表述&#xff1a;&#xff08;3&#xff09;代码实现&#xff1a; 2.用队列实现栈&#xff08;1&#xff09;题目描述&#xff1a;&#xff08;2&#xff09;思路表述&…

java double类型保留两位小数并去除后面多余的0

public static void main(String[] args) {double value9.100001;//保留两位小数String format String.format("%.2f", value);//去除多余的0String strValue new BigDecimal(format).stripTrailingZeros().toPlainString();System.out.println("strValue &q…

三维模型重建中地面控制点刺点输入常见问题及解决方法

三维模型重建中地面控制点刺点输入常见问题及解决方法 在倾斜摄影三维模型重建中&#xff0c;地面控制点的人工刺点输入是一个重要的环节。然而&#xff0c;这个过程可能会遇到一些常见问题。以下是一些常见问题及相应的解决方法&#xff1a; 1、问题&#xff1a;标定点位置不…

48、Flink DataStream API 编程指南(1)- DataStream 入门示例

Flink 系列文章 1、Flink 部署、概念介绍、source、transformation、sink使用示例、四大基石介绍和示例等系列综合文章链接 13、Flink 的table api与sql的基本概念、通用api介绍及入门示例 14、Flink 的table api与sql之数据类型: 内置数据类型以及它们的属性 15、Flink 的ta…

webpack优化打包速度

webpack打包速度太慢 优化 1.多线程打包 js压缩和loader 2.优化启动速度 hard-source-webpack-plugin 3.删除无用的 分析类插件 4.DllPlugin通道打包 1.webpack多线程打包 loader loader 使用 thread-loader 将他放置你要使用的loader前面就行&#xff0c;不过这个lorder例如s…

第二证券:股票几点到几点开盘?

作为股民或许投资者&#xff0c;我们都知道股票是每天都有开盘和收盘时间的。但是&#xff0c;关于股票的开盘时间&#xff0c;很多人并不是很清楚&#xff0c;特别是初学者。在本文中&#xff0c;我们将从多个视点分析股票开盘时间&#xff0c;并为大家供给一些有用的信息。 …