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

欢迎关注个人主页:逸狼


创造不易,可以点点赞吗~

如有错误,欢迎指出~



目录

LIst

顺序表ArrayList

顺序表优点

IList接口

ArrayList中定义要操作的数组

[在MyArrayList中 重写接口方法](#在MyArrayList中 重写接口方法)

新增元素

在指定位置插入元素

pos不合法异常

判断和查找元素

获取和更新元素

删除元素和清空顺序表

获取顺序表的长度和打印顺序表


LIst

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

  • ArrayList:实现了List接口,底层为动态类型顺序表
  • LinkedList:实现了List接口,底层为双向链表

Java类和接口总览

顺序表ArrayList

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

顺序表优点

适合根据下标进行 查找 和 更新的场景

访问速度比较快(在给定下标的情况下可以达到O(1)

下面我们要自己模拟实现一个 顺序表MyArrayList,理解它底层的数据结构原理,方便我们未来更好的使用ArrayList中的方法。

IList接口

复制代码
package arrayList;

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

     boolean isFull();
}

ArrayList中定义要操作的数组

复制代码
package arrayList;

import java.util.Arrays;
//定义顺序表,实现IList 接口
public class MyArrayList implements IList{

    //定义要操作的数组
    public int[]elem;
    public int usedSize;//数组中存储的数据个数

    public MyArrayList(){
        this.elem=new int[10];//表示数组长度是10

    }

在MyArrayList中 重写接口方法

新增元素

复制代码
    @Override     // 新增元素,默认在数组最后新增
    public void add(int data) {
        //如果满了,要扩容
        if(isFull()){
            //扩容
            elem= Arrays.copyOf(elem,2*elem.length);
        }
        this.elem[usedSize]=data;
        this.usedSize++;
    }

    @Override//用于判断顺序表是否满了
    public boolean isFull() {
        return usedSize==elem.length;
    }

在指定位置插入元素

复制代码
@Override     // 在 pos 位置新增元素
    public void add(int pos, int data) {
        //插入数据的时候一定要保证插入的位置前面有数据
        try{
            checkPosOfAdd(pos);
        }catch (PosNotLegalException e){
            e.printStackTrace();
        }
        //判断是否满了
        if(isFull()){
            elem= Arrays.copyOf(elem,2*elem.length);
        }
        //移动元素
        for (int i = usedSize-1; i>=pos  ; i--) {
            elem[i+1]=elem[i];
        }
        //插入元素
        elem[pos]=data;
        usedSize++;
    }

    //该方法用来 判断添加元素时 pos是否合法
    private void checkPosOfAdd(int pos){
        if(pos<0||pos>usedSize){
            throw new PosNotLegalException("在pos位置插入元素时Pos位置不合法。。。");//抛出一个异常
        }
    }

pos不合法异常

复制代码
package arrayList;
//定义一个异常,用于对pos不合法时的报警
public class PosNotLegalException extends RuntimeException{
    public PosNotLegalException(){

    }
    public PosNotLegalException(String msg){
        super(msg);
    }
}

判断和查找元素

复制代码
    @Override     // 判定是否包含某个元素
    public boolean contains(int toFind) {
        //只需要找usedSize次
        for (int i = 0; i < usedSize; i++) {
            if(elem[i]==toFind){
                return true;
            }
        }
        return false;
    }

    @Override     // 查找某个元素对应的位置
    public int indexOf(int toFind) {
        for (int i = 0; i < usedSize; i++) {
            if(elem[i]==toFind){
                return i;//与上面contains方法的代码一样,只是返回的是下标
            }
        }
        return -1;
    }

获取和更新元素

复制代码
 //get/set时,判断pos是否合法
    private void checkPosOfGet(int pos)throws PosNotLegalException{
        if(pos<0||pos>=usedSize){
            throw new PosNotLegalException("get/set获取元素的时候pos位置不合法。。。");
        }
    }
    @Override     // 获取 pos 位置的元素
    public int get(int pos) {
        try{
            checkPosOfGet(pos);
        }catch (PosNotLegalException e){
            e.printStackTrace();
        }
        return elem[pos];
    }

    @Override     //给 pos 位置的元素设为 value   更新pos位置的值为value
    public void set(int pos, int value) {
        try{
            checkPosOfGet(pos);
        }catch (PosNotLegalException e){
            e.printStackTrace();
        }
        elem[pos]=value;
    }

删除元素和清空顺序表

复制代码
 @Override     //删除第一次出现的关键字key
    public void remove(int toRemove) {
        //要查找是否查找要删除的关键字 toRemove
        int pos =indexOf(toRemove);
        if(pos==-1){
            System.out.println("没有要删除的数字!");
            return;
        }
        for (int i = 0; i < usedSize-1; i++) {
            elem[i]=elem[i+1];
        }
        usedSize--;
    }


    @Override     // 清空顺序表
    public void clear() {
        //1.如果是数组元素,直接将usedSize置为0
        //2.如果是引用类型,则置为null
        /*        for (int i = 0; i < usedSize; i++) {
            elem[i]=null;
        }*/
        usedSize=0;//这里是数组


    }

获取顺序表的长度和打印顺序表

复制代码
@Override     // 获取顺序表长度
    public int size() {
        return usedSize;
    }

    @Override //打印顺序表
    public void display() {
        for (int i = 0; i < usedSize; i++) {
            System.out.print(elem[i]+" ");
        }
        System.out.println();
    }
相关推荐
skilllite作者1 天前
Spec + Task 作为「开发协议层」:Rust 大模型辅助的标准化、harness 化与可回滚
开发语言·人工智能·后端·安全·架构·rust·rust沙箱
Dxy12393102161 天前
Python序列标注模型上下文纠错详解
开发语言·python
孙鹏宇.1 天前
左值右值.
java·开发语言
XDHCOM1 天前
Redis节点故障自动恢复机制详解,如何快速抢救故障节点,确保数据不丢失?
java·数据库·redis
风吹迎面入袖凉1 天前
【Redis】Redisson分布式锁原理
java·服务器·开发语言
A.A呐1 天前
【QT第五章】系统相关
开发语言·qt
QCzblack1 天前
BugKu BUUCTF ——Reverse
java·前端·数据库
Orange_sparkle1 天前
learn claude code学习记录-S02
java·python·学习
李白你好1 天前
Java GUI-未授权漏洞检测工具
java·开发语言
leo__5201 天前
拉丁超立方抽样(Latin Hypercube Sampling, LHS)MATLAB实现
开发语言·matlab