【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();
    }
相关推荐
北i4 分钟前
Dubbo 默认超时重试:把下游打雪崩的隐形放大器
开发语言·qt·dubbo
信奥卷王6 分钟前
[GESP202606 六级] 满二叉树
数据结构·算法
10mAh15 分钟前
【Java】ArrayList 遍历删除为什么报错?三种写法与漏删复现
java·开发语言·windows
thefool11226631 分钟前
多线程 4
java
wewowilling36 分钟前
AI大模型开发--01Python基础(无废话)
开发语言·python·函数
小羊没烦恼!44 分钟前
OS X 上使用.NET开发应用程序
开发语言·前端·数据库·人工智能·c#·策略模式
棉猴1 小时前
玩游戏学Python5-函数
开发语言·python·函数·玩游戏·游戏编程
Rain的Java大神之路1 小时前
[特殊字符]8年Java老兵转型AI Agent:90%的人挂在同一个坑,根本不用学Python!(万字实战复盘,建议收藏)
java·数据库·人工智能·后端·python·spring·ai编程
高级程序源1 小时前
springboot大学生体测系统72170-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·python·django·课程设计
谢亮_vipxieliang1 小时前
JavaScript this 指向完全指南:调用位置决定一切
开发语言·javascript·ecmascript