【数据结构】ArrayList的模拟实现--Java

news2024/12/23 14:57:34

目录

 一、🍩简单了解ArrayList

二、🍩ArrayList的简单模拟实现

1.🍔IList接口

1.🍕IList接口

2. 🍕 MyArrayList 重写接口方法

2.🍔ArrayList方法

1.🥪增

1.add(添加元素):添加在末尾

 2.add(插入元素):插入元素在任意位置

2.🥪 查

1.contains(是否包含该元素)

2.get(获取下标元素)

3.indexOf (获取元素下标)

3.🥪删

 1.remove(删除元素)

2.clear(清空所有元素)

4.🥪改

1.set(更改元素):将元素进行替换


 一、🍩简单了解ArrayList

什么是ArrayList?

在集合框架中,ArrayList是一个普通的类,其内部基于数组实现,数据存储有序,实现的List接口。List是一个接口不能进行实例化,而ArrayList实现了这个接口。

  • List就是一个线性表,即具有n个相同类型元素的有限序列,在该序列上可以执行增删查改的功能以及变量等操作。 

二、🍩ArrayList的简单模拟实现

1.🍔IList接口

      首先,我们知道ArrayList实现了List的接口,所以我们要知道List接口中有哪些方法,并且ArrayLiat要重写List接口中的方法这里我们对其是简单模拟ArrayList,我们实现其一些常见的功能就好。

ArrayList常见方法:

增:
void add(int data)在数组最后添加元素
void add(int pos,int data)在数组某下标插入元素
删:
void remove(int toRemove)删除第一次出现的元素
void clear();清空所有元素
查:

boolean contains(int toFind)

查看是否包含该元素
int get(int pos)获取该下标元素
int indexOf(int toFind )获取该元素下标
改:
void set(int pos,int value)将下标元素进行更改

 这些常见方法就是增删查改的功能。

1.🍕IList接口

public interface IList {
    public void add(int data);
    public void add(int pos,int data);
    public void remove(int toRemove);
    public void clear();
    public boolean contains(int toFind);
    public int get(int pos);
    public int indexOf(int toFind);
    public void set(int pos,int value);
}

2. 🍕 MyArrayList 重写接口方法

public class MyArrayList implements IList{
    @Override
    public void add(int data) {

    }
    @Override
    public void add(int pos, int data) {

    }
    @Override
    public void remove(int toRemove) {

    }
    @Override
    public void clear() {

    }
    @Override
    public boolean contains(int toFind) {
        return false;
    }
    @Override
    public int get(int pos) {
        return 0;
    }
    @Override
    public int indexOf(int toFind) {
        return 0;
    }
    @Override
    public void set(int pos, int value) {

    }
}

我们知道,ArrayList内部是基于数组内部实现, 并且他是一个有限序列,所以我们需要在MyArrayList中加几个定义的变量

public class MyArrayList implements IList{
    public int[] array;
    //默认容量大小
    //这个为常量,所以可以使用static final
    public static final int DEFULATE_CAPACITY=10;
    //以占用的数组空间大小
    public int usedsize;
    //构造方法
    public MyArrayList() {
        this.array = new int[DEFULATE_CAPACITY];
    }
}

2.🍔ArrayList方法

1.🥪增

1.add(添加元素):添加在末尾

注意事项:

  • 是否空间已满,如果满了进行扩容;
  • 添加了代码之后,使用空间增加。
public void add(int data) {
        //如果满了,进行扩容
        if(isFull()){
            grows();
        }
        //数组下标由0开始,在增加一个元素的时候,其下标在第usedsize的位置上
        array[usedsize]=data;
        usedsize++;
    }

判断空间是否已满(isFull):使用空间==空间大小

    public boolean isFull(){
        return this.usedsize==array.length;
    }

 扩容(grows):使用Arrays.copyOf进行扩容

   public void grows(){
        this.array= Arrays.copyOf(this.array,
                2*this.array.length);
    }

  为了更好的查看结果,我们需要加上一个打印方法

展示:注意这里的i是小于数组以使用的长度usedsize而不是数组的全部长度

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

测试:

public class Test {
    public static void main(String[] args) {
        MyArrayList myArrayList=new MyArrayList();
        myArrayList.add(1);
        myArrayList.add(2);
        myArrayList.add(3);
        myArrayList.add(1);
        myArrayList.add(2);
        myArrayList.add(3);
        myArrayList.add(1);
        myArrayList.add(2);
        myArrayList.add(3);
        myArrayList.add(1);
        myArrayList.add(2);
        myArrayList.add(3);
        myArrayList.display();
    }
}

结果: 

 46705e0757ed4c279d1061b15072cff4.png

 2.add(插入元素):插入元素在任意位置

注意事项:

1.插入元素的下标不能小于0以及不能大于usedsize,否则·报错;

2.插入空间是否已满,满了扩容;

3.已使用数组长度增加;

我们需要检查添加的下标位置是否合法,由于可能会出现位置不合法的情况,如果出现这种情况,要报错,所以我们需要自定义一个位置不合法异常

PosIlleagal类:继承运行时异常

public class PosIllegal extends RuntimeException{
    public PosIllegal() {
        super();
    }
    public PosIllegal(String message) {
        super(message);
    }
}

出现异常条件:插入元素的下标不能小于0以及不能大于usedsize

checkPos:检查插入元素的下标是否合法

  //throws:其提醒作用,可能存在的异常
    public void checkPos(int pos) throws PosIllegal{
        //如果下标位置不合法,报错
        if(pos < 0 || pos >= usedsize){
            throw new PosIllegal("位置不合法!!!");
        }
    }

既然可能会出现异常,我们需要对其进行try-catch捕获处理

    public void add(int pos, int data) {
        try{
            checkPos(pos);
            if(isFull()){
                grows();
            }
        }catch (PosIllegal e){
            System.out.println("下标插入位置不合法");
            e.printStackTrace();
        }catch(Exception e){
            e.printStackTrace();
        }
    }

 add(插入元素):我们可以从后往前,将前面的元素向后移动,直到移动到所需插入元素的下标为止,随即插入元素

   public void add(int pos, int data) {
        try{
            checkPos(pos);
            if(isFull()){
                grows();
            }
            for (int i = usedsize-1; i >=pos ; i--) {
                array[i+1]=array[i];
            }
            array[pos]=data;
            usedsize++;
        }catch (PosIllegal e){
            System.out.println("下标插入位置不合法");
            e.printStackTrace();
        }catch(Exception e){
            e.printStackTrace();
        }
    }

测试:

   public static void main(String[] args) {
        MyArrayList myArrayList=new MyArrayList();
        myArrayList.add(1);
        myArrayList.add(2);
        myArrayList.add(3);
        myArrayList.add(3,11);
        myArrayList.add(6,5);
        myArrayList.display();
    }

结果: 

 fc59e73a8d8a4178b69fd65218e840f5.png

2.🥪 查

1.contains(是否包含该元素)

  contains:遍历所使用的数组大小,查找是否有该元素

    @Override
    public boolean contains(int toFind) {
        for (int i = 0; i < usedsize; i++) {
            if(array[i]==toFind){
                return true;
            }
        }
        return false;
    }

2.get(获取下标元素)

 注意事项:

1.该数组是否为空,如果为空,报错

1.该下标是否合法,如果下标小于0或者下标大于等于usedsize,那么位置不合法;

  注意:这里的是大于等于,插入元素的不合法是大于

既然我们在使用get方法的时候会出现顺序表为空的情况下,那么我们需要一个顺序表为空时候的异常

EmptyException(顺序表为空异常):

public class EmptyException extends RuntimeException{
    public EmptyException() {
    }

    public EmptyException(String message) {
        super(message);
    }
}

checkEmpty(顺序表报错条件):

   public void checkEmpty() throws EmptyException{
        if(usedsize==0){
            throw new EmptyException("顺序表为空");
        }
    }

由于这样的位置不合法条件与插入元素的位置不合法条件不同,所以我们需要再写一个检查位置是否合法的方法

checkPos2(检查pos位置是否合法):

   public void checkPos2(int pos) throws PosIllegal{
        if(pos < 0 || pos >= usedsize){
            throw new PosIllegal("位置不合法!!!");
        }
    }

get:如果没有出现异常,直接返回下标元素

public int get(int pos) {
        try {
            checkEmpty();
            checkPos2(pos);
            return array[pos];
        }catch (PosIllegal e){
            System.out.println("Pos位置不合法");
            e.printStackTrace();
        }catch (EmptyException e){
            System.out.println("顺序表为空");
            e.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }
        return -1;
    }

3.indexOf (获取元素下标)

注意事项:

1.是否包含该元素,如果没有返回-1;

indexOf:遍历数组元素,查找是否有该元素,有则返回元素下标,没有返回-1 

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

 测试:

 public static void main(String[] args) {
        MyArrayList myArrayList=new MyArrayList();
        myArrayList.add(1);
        myArrayList.add(2);
        myArrayList.add(3);
        //是否包含
        boolean b=myArrayList.contains(5);
        System.out.println(b);//false
        //获取下标元素
        int a=myArrayList.get(2);
        System.out.println(a);//3
        //获取元素下标
        int c=myArrayList.indexOf(0);
        System.out.println(c);//-1
        int d=myArrayList.indexOf(3);
        System.out.println(d);//2
    }

结果: 

f240ab6935054223bf12264339af1029.png

3.🥪删

 1.remove(删除元素)

注意事项:

1.顺序表是否为空;

2.是否有该元素;

3.如果删除完该元素,数组使用长度减小。

remove:获取下标,如果下标不存在,返回;如果下标存在,将下标从前往后遍历,将后面的元素向前移动 

public void remove(int toRemove) {
       try{
           checkEmpty();
           //获取下标
           int pos=indexOf(toRemove);
           if(pos==-1){
               System.out.println("没有该元素,移除失败");
               return;
           }
           //从前往后,将后面的元素向前移动
           //i是小于usedsize-1就好,因为当i=usedsize-2
           //将usedsize-1中的元素移到了usedsize-2中
           for (int i = pos; i < usedsize-1; i++) {
                  array[i]=array[i+1];
           }
           usedsize--;
       }catch (EmptyException e){
           System.out.println("顺序表为空");
           e.printStackTrace();
       }catch(Exception e){
           e.printStackTrace();
       }
    }

2.clear(清空所有元素)

clear:直接将使用空间置0;

 public void clear() {
        this.usedsize=0;
    }

测试:

    public static void main(String[] args) {
        MyArrayList myArrayList=new MyArrayList();
        myArrayList.add(1);
        myArrayList.add(2);
        myArrayList.add(3);
        myArrayList.display();
        System.out.println();//1 2 3
        //移除:
        myArrayList.remove(2);
        myArrayList.display();
        System.out.println();//1 3
        myArrayList.remove(5);//没有该元素,移除失败
        System.out.println();
        //清空:
        myArrayList.clear();
        myArrayList.display();
        myArrayList.add(1);
        myArrayList.display();//1
    }

c92016dd477e447bacf73d0d22e16471.png

4.🥪改

1.set(更改元素):将元素进行替换

注意事项:

1.顺序表是否为空;

2.进行更改的元素下标是否合法

set:直接将下标所对于的元素进行更改 

public void set(int pos, int value) {
        try{
            checkEmpty();
            checkPos2(pos);
            array[pos]=value;
        }catch (EmptyException e){
            System.out.println("顺序表为空");
            e.printStackTrace();
        }catch (PosIllegal e){
            System.out.println("下标位置不合法");
            e.printStackTrace();
        }catch(Exception e){
            e.printStackTrace();
        }
    }

测试:

public static void main(String[] args) {
        MyArrayList myArrayList=new MyArrayList();
        myArrayList.add(1);
        myArrayList.add(2);
        myArrayList.add(3);
        myArrayList.display();//1 2 3
        System.out.println();
        myArrayList.set(2,11);//1 2 11
        myArrayList.display();
        System.out.println();
        myArrayList.set(5,11);//报错
        myArrayList.display();
    }

结果:

 1eed3f969c7941038993ccabb945c328.png

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

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

相关文章

数据结构+算法

一、数据结构 1、线性结构 数组&#xff1a; 访问&#xff1a;O(1)访问特定位置的元素&#xff1b;插入&#xff1a;O(n)最坏的情况发生在插入发生在数组的首部并需要移动所有元素时&#xff1b;删除&#xff1a;O(n)最坏的情况发生在删除数组的开头发生并需要移动第一元素后…

go 聊天系统项目-1

1、登录界面 说明&#xff1a;这一节的内容采用 go mod 管理【GO111MODULE‘’】的模块&#xff0c;从第二节开始使用【GO111MODULE‘off’】GOPATH 管理模块。具体参见 go 包相关知识 1.1登录界面代码目录结构 代码所在目录/Users/zld/Go-project/day8/chatroom/ 1.2登录…

Steam deck 倒腾日记 - 安装Windows软件,玩上黑神话悟空

Steam deck 倒腾日记 关于Steam Deck基本信息性能特点游戏兼容性 问题一: 软键盘输入问题二: 系统切换问题三: 安装运行Window 软件关于Proton如何运行 问题四: 优化网络问题黑神话.悟空PS参考 关于Steam Deck Steam Deck是一款由Valve开发的便携式游戏PC&#xff0c;它搭载了A…

【内网渗透】最保姆级的2022网鼎杯半决赛复盘打靶笔记

目录 flag1 flag2 flag3 flag4 flag1 fscan什么也没扫到 访问是个web dirsearch开扫 访问./wp-admin 弱口令admin:123456登录 编辑主题文件 在header.php中插入一句话木马 header.php位置&#xff1a;https://tw.godaddy.com/help/change-the-header-in-wordpress-264…

Python 实现斐波那契数列的方法

以下是使用 Python 实现斐波那契数列的方法&#xff1a; def fibonacci(n): if n < 1: return n else: return fibonacci(n - 1) fibonacci(n - 2) # 打印前 10 个斐波那契数 for i in range(10): print(fibonacci(i)) 在这个代码中&#xff0c;定义了一个函数 fibonacc…

IntelliJ IDEA 中上传项目到 Gitee 的完整指南

博主主页:【南鸢1.0】 本文专栏&#xff1a;git 目录 简介 1.插入intellij-gitee 2.导入下载插件 3.选择导航栏中的VCS->Share Project on Gitee 4.登录gitee 6.验证gitee仓库是否创建成功 7.上传分享项目 8.验证仓库代码是否上传成功 总结 简介 Gitee 是一个代码…

【p2p、分布式,区块链笔记 分布式容错算法】: 拜占庭将军问题+实用拜占庭容错算法PBFT

papercodehttps://pmg.csail.mit.edu/papers/osdi99.pdfhttps://github.com/luckydonald/pbft 其他相关实现&#xff1a;This is an implementation of the Pracltical Byzantine Fault Tolerance protocol using PythonAn implementation of the PBFT consensus algorithm us…

简单的kafkaredis学习之redis

简单的kafka&redis学习之redis 2. Redis 2.1 什么是Redis Redis是一种面向 “Key-Value” 数据类型的内存数据库&#xff0c;可以满足我们对海量数据的快速读写需求&#xff0c;Redis是一个 NoSQL 数据库&#xff0c;NoSQL的全称是not only sql&#xff0c;不仅仅是SQL&…

无人机之卫星通信技术篇

无人机的卫星通信技术是一种利用人造地球卫星作为中继站来转发无线电波&#xff0c;从而实现无人机与地面控制站之间通信的技术。 一、技术概述 卫星通信系统主要由通信卫星和经该卫星连通的地球站两部分组成。在无人机应用中&#xff0c;卫星通信技术能够确保无人机在全球范围…

网鼎杯 misc -好久不见4

不嘻嘻&#xff0c;没见过这种题&#xff0c;需要把这个红线还原重组成二维码&#xff0c;搜索一个是这个Peano曲线 from PIL import Image from tqdm import tqdmdef peano(n):if n 0:return [[0, 0]]else:in_lst peano(n - 1)lst in_lst.copy()px, py lst[-1]lst.extend(…

ARM base instruction -- adcs

Add with Carry, setting flags, adds two register values and the Carry flag value, and writes the result to the destination register. It updates the condition flags based on the result. 带进位加法&#xff0c;设置标志&#xff0c;将两个寄存器值和进位标志值相…

笔记本双系统win10+Ubuntu 20.04 无法调节亮度亲测解决

sudo add-apt-repository ppa:apandada1/brightness-controller sudo apt-get update sudo apt-get install brightness-controller-simple 安装好后找到一个太阳的图标&#xff0c;就是这个软件&#xff0c;打开后调整brightness&#xff0c;就可以调整亮度&#xff0c;可…

vue版本太低无法执行vue ui命令

连接 ui和create目前都只支持3.0以后得版本才能使用 https://blog.csdn.net/m0_67318913/article/details/136775252?utm_mediumdistribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-0-136775252-blog-121204604.235v43pc_blog_bottom_relevance…

萤石私有化设备视频平台EasyCVR视频融合平台如何构建农业综合监控监管系统?

现代农业的迅速发展中&#xff0c;集成监控管理系统已成为提高农业生产效率和优化管理的关键工具。萤石私有化设备视频平台EasyCVR&#xff0c;作为一个具有高度可扩展性、灵活的视频处理能力和便捷的部署方式的视频监控解决方案&#xff0c;为农业监控系统的建设提供了坚实的技…

Pr 视频效果:闪光灯

视频效果/风格化/闪光灯 Stylize/Strobe Light 闪光灯 Strobe Light效果可用于在视频中创建闪烁或频闪的效果&#xff0c;类似于舞台上的频闪灯或摄影中的闪光灯。 ◆ ◆ ◆ 效果选项说明 通过调整各种参数&#xff0c;可以自定义闪光的颜色、频率、持续时间和混合模式&#…

FreeRTOS确定任务栈大小

一、FreeRTOS内存分配 所有任务共用一个堆空间&#xff0c;所以当调用xPortGetFreeHeapSize这个函数时&#xff0c;返回的就是现在所有可用堆空间的消息 所有任务都有自己的栈空间&#xff0c;比如在任务中定义一个uint32_t data[100]的数组&#xff0c;此时调用uxTaskGetSt…

计算机毕业设计Hadoop+Spark+Hive抖音情感分析 抖音可视化 抖音舆情监测 预测算法 抖音爬虫 抖音大数据 情感分析 NLP 自然语言处理

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; HadoopSparkHive抖音情感分…

tcp shutdown, fin_wait1, fin_wait2, close_wait, last_ack, 谢特!

TCP 作为双向传输协议&#xff0c;如果你想只收不发&#xff0c;可以单向关掉发&#xff0c;shutdown(socket.SHUT_WR)&#xff0c;但不建议这么做。 看以下代码&#xff1a; #!/Users/zhaoya/myenv/bin/python3 # client import socketclient_socket socket.socket(socket.…

redis安装使用

1. 下载地址 :::color1 下载最新稳定版本的 redis-windows 7.x 版本(本实例以 7.2.3 为例) ::: # 下载地址 https://download.csdn.net/download/qq827245563/899238402. 解压文件 ![](https://img-blog.csdnimg.cn/img_convert/c094d561f7f8ed6e9d139d07be1271cb.png) 3. …

如果在 Ubuntu 24.04 上安装 Yarn ?

Yarn 是一种快速、可靠、安全的 JavaScript 项目依赖管理工具&#xff0c;它提供了比同类产品更好的缓存机制、网络性能和更直观的用户界面。作为现代 web 开发的基本工具&#xff0c;在系统上安装 Yarn 可以确保您可以有效地管理项目依赖关系。 他的文章将指导您通过 4 种有效…