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

欢迎关注个人主页:逸狼

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

如有错误,欢迎指出~

目录

LIst

顺序表ArrayList

顺序表优点

IList接口

ArrayList中定义要操作的数组

在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();
    }

版权声明:本文为博主作者:逸狼原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/2301_80898480/article/details/138037782

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
青葱年少的头像青葱年少普通用户
上一篇 2024年5月6日
下一篇 2024年5月6日

相关推荐