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

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:本次内容就到这里结束了,喜欢的话,还请大家一键三连哦!!! 

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

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

相关文章

【HTML】VScode不打开浏览器实时预览html

1. 问题描述 预览HTML时&#xff0c;不想打开浏览器&#xff0c;想在VScode中直接实时预览 2. 解决方案 下载Microsoft官方的Live Preview 点击预览按钮即可预览

图面试专题

一、概念 和二叉树的区别&#xff1a;图可能有环 常见概念 顶点&#xff08;Vertex&#xff09;&#xff1a; 图中的节点或点。边&#xff08;Edge&#xff09;&#xff1a; 顶点之间的连接线&#xff0c;描述节点之间的关系。有向图&#xff08;Directed Graph&#xff09;&…

力扣题:字符的统计-12.1

力扣题-12.1 [力扣刷题攻略] Re&#xff1a;从零开始的力扣刷题生活 力扣题1&#xff1a;451. 根据字符出现频率排序 解题思想&#xff1a;统计字符出现的个数&#xff0c;进行排序即可 class Solution(object):def frequencySort(self, s):""":type s: str:…

Spine深入学习 —— 换装

Spine深入学习————换装 数据对象和实例对象的关系与区别 数据对象是无状态的&#xff0c;可在任意数量的骨架实例间共用。有对应实例数据的数据对象类名称以“Data”结尾&#xff0c;没有对应实例数据的数据对象则没有后缀&#xff0c;如附件、皮肤及动画。 实例对象有许…

UWB高精度定位系统项目源码

在现代社会中&#xff0c;精准定位技术对于各行各业都至关重要。为了满足对高精度定位的需求&#xff0c;超宽带&#xff08;Ultra-Wideband, UWB&#xff09;技术应运而生。UWB高精度定位系统以其出色的定位精度和多样化的应用领域而备受关注。本文将深入探讨UWB高精度定位系统…

机器学习:DBSCAN算法(效果比K-means好)

基本概念 核心对象&#xff1a;以点为圆心半径为r的圆&#xff0c;如果圈里面的样本点大于给定的阈值(minPts)&#xff0c;那么这个点就叫做核心点 直接密度可达&#xff1a;点p在q为圆心的圆内 密度可达&#xff1a; p1与p2直接密度可达&#xff0c;p2与p3直接密度可达&…

基于社区电商的Redis缓存架构-缓存数据库双写、高并发场景下优化

基于社区电商的Redis缓存架构 首先来讲一下 Feed 流的含义&#xff1a; Feed 流指的是当我们进入 APP 之后&#xff0c;APP 要做一个 Feed 行为&#xff0c;即主动的在 APP 内提供各种各样的内容给我们 在电商 APP 首页&#xff0c;不停在首页向下拉&#xff0c;那么每次拉的…

通达OA inc/package/down.php接口未授权访问漏洞复现 [附POC]

文章目录 通达OA inc/package/down.php接口未授权访问漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 通达OA inc/package/down.php接口未授权访问漏洞复现 [附POC] 0x01 前言 免责声明&#x…

el-row错位问题解决

<el-row type"flex" style"flex-wrap:wrap">

突破界限:R200科研无人车,开辟研究新天地

提到科研无人车&#xff0c;大家可能首先想到的是其在自动驾驶和其他先进技术领域的应用。然而&#xff0c;随着科技的不断进步&#xff0c;科研无人车已经在智慧城市建设、商业服务、地质勘探、环境保护、农业技术革新、灾害应急和自动化服务等多个领域发挥着至关重要的作用。…

股东信息API:如何通过API获取企业股东构成的全貌

前言 在当今数字化时代&#xff0c;信息的获取和分析变得至关重要&#xff0c;特别是对于投资者和企业决策者而言。股东信息是企业治理中一个关键的方面&#xff0c;了解企业的股东构成有助于投资决策、风险管理以及业务战略的制定。本文将探讨股东信息API&#xff0c;介绍如何…

unity UI特效遮罩

using System.Collections; using System.Collections.Generic; using UnityEngine;/**UI特效遮罩 1.需要将ScrollRect 的遮罩Mask 换为 2D Mask2.将特效的Render里面的 Masking 设置为*/ public class UIParticleMaskControll : MonoBehaviour {// Start is called before …

全网最细图解知识蒸馏(涉及知识点:知识蒸馏训练过程,推理过程,蒸馏温度,蒸馏损失函数)

一.是什么&#xff1f; 把一个大的模型(定义为教师模型)萃取&#xff0c;蒸馏&#xff0c;把它浓缩到小的模型(定义为学生模型)。即&#xff1a;大的神经网络把他的知识教给了小的神经网络。二.为什么要用知识蒸馏把大模型学习到的东西迁移到小模型呢呢&#xff1f; 因为大的…

需求不明确的情况下,测试该如何处理?

当需求不明确的情况下&#xff0c;测试团队可以采取以下措施来处理&#xff1a; 1. 与项目团队进行沟通&#xff1a;测试团队应与项目团队密切合作&#xff0c;与业务分析师、产品经理等相关人员进行沟通&#xff0c;以获取更多的需求细节和背景信息。通过与相关方的交流&…

力扣日记11.30-【二叉树篇】平衡二叉树

力扣日记&#xff1a;【二叉树篇】平衡二叉树 日期&#xff1a;2023.11.30 参考&#xff1a;代码随想录、力扣 110. 平衡二叉树 题目描述 难度&#xff1a;简单 给定一个二叉树&#xff0c;判断它是否是高度平衡的二叉树。 本题中&#xff0c;一棵高度平衡二叉树定义为&#…

JVM——产生内存溢出原因

目录 1.产生内存溢出原因一 &#xff1a;代码中的内存泄漏1.案例1&#xff1a;equals()和hashCode()导致的内存泄漏问题&#xff1a;**正常情况**&#xff1a;**异常情况&#xff1a;**解决方案&#xff1a; 2.案例2&#xff1a;内部类引用外部类问题&#xff1a;解决方案&…

深度学习-模型调试经验总结

1、 这句话的意思是&#xff1a;期望张量的后端处理是在cpu上&#xff0c;但是实际是在cuda上。排查代码发现&#xff0c;数据还在cpu上&#xff0c;但是模型已经转到cuda上&#xff0c;所以可以通过把数据转到cuda上解决。 解决代码&#xff1a; tensor.to("cuda")…

奇葩问题:arp缓存、ip地址冲突(实际是ip地址被占用导致arp缓存出现问题)

文章目录 今天遇到个奇葩的问题 今天遇到个奇葩的问题 今天遇到个奇葩的问题&#xff0c;我把我们192.168.1.116的盒子ip改成192.168.2.116后&#xff0c;再改回来&#xff0c;发现我们盒子的http服务始终无法访问&#xff0c;用Advanced IP Scanner扫描一下&#xff0c;发现就…

Python with提前退出:坑与解决方案

Python with提前退出&#xff1a;坑与解决方案 问题的起源 早些时候使用with实现了一版全局进程锁&#xff0c;希望实现以下效果&#xff1a; Python with提前退出&#xff1a;坑与解决方案 全局进程锁本身不用多说&#xff0c;大部分都依靠外部的缓存来实现的&#xff0c;r…

安全技术与防火墙

目录 安全技术 防火墙 按保护范围划分: 按实现方式划分: 按网络协议划分. 数据包 四表五链 规则链 默认包括5种规则链 规则表 默认包括4个规则表 四表 查询 格式&#xff1a; 规则 面试题 NFS常见故障解决方法 安全技术 入侵检测系统 (Intrusion Detection Sy…