Java 代码模拟实现顺序表 + 标准库中ArrayList的使用


前言

本篇文章可以是数据结构的开篇作,数据结构作为数据存储方面的学科,其中的魅力也是让人着迷的。加油啊,各位!!


一、模拟实现顺序表

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


成员变量

  1. 🤖用来存储数据的数组,array
  2. 🤖用来记录已存储的数据个数,size
public class MySeqList {
    private int[] array;//存储数据的数组
    private int size;//数据个数
}

1.构造方法

    //无参数的构造方法
    public MySeqList() {
        //默认将底层容量大小设置为10
        this.array = new int[10];
    }

    //有参数的构造方法
    public MySeqList(int initcapacity) {
        //将顺序表的底层容量设置为initcapacity
        this.array = new int[initcapacity];
    }

2.add方法——新增数据

  • 在填加数据前,咱们要考虑是否还有剩余容量可以存储填加进来的数据,如果没有那么就会产生越界访问。

所以需要提供一个判断容量是否已满的方法。
不需要提供给用户,且只在类中使用,所以要用private封装起来。

    //判断顺序表是否满了
    private boolean isFull() {
        if(size == array.length) {
            return true;
        }
        return false;
    }

如果数据满了,那么就要进行扩容,所以要提供一个扩容方法
不需要提供给用户,且只在类中使用,所以要用private封装起来。

//扩容方法,将容量扩大两倍
    private void dilatancy() {
        this.array = Arrays.copyOf(this.array,size*2);
    }

1.默认新增方法

默认新增方法,即默认在数组最后进行存储

    // 新增元素,默认在数组最后新增
    public void add(int data) {
        //如果顺序表满了,为其进行扩容
        if(isFull()) {
            dilatancy();
        }

        //将数据存储进去,并更新数据个数
        array[size++] = data;
    }

2.在指定位置新增方法

顺序表的数据一定要连续存储。

所以在插入数据前我们要判断指定位置是否合法。
在这里插入图片描述
如上图,下标0,1,2,3的位置都存储了数据,
那么可以在0,1,2,3,4的位置插入数据,其他位置均不合法。

    private boolean judgeAddPos(int pos) {
        if(pos < 0 || pos > size) {
            return false;
        }
        return true;
    }

如果位置不合法,那么我们可以抛出一个运行时异常。

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

在这里插入图片描述


所以在指定位置新增数据的方法就是:

    // 在 pos 位置新增元素
    public void add(int pos, int data) {
        if(isFull()) {
            dilatancy();
        }
        if(!judgeAddPos(pos)) {
            throw new SeqListIndexOutOfException("输入位置不合法");
        }

        //将要插入数据位置及其后的数据,整体向后挪
        for (int i = size; i > pos ; i--) {
            array[i] = array[i-1];
        }
        array[pos] = data;//插入数据
        size++;//更新数据个数
    }

3. contains——判定是否包含某个元素

    // 判定是否包含某个元素
    public boolean contains(int toFind) {
		//遍历所有数据,如果找到就返回true
        for (int i = 0; i < size; i++) {
            if(array[i] == toFind) {
                return true;
            }
        }
        return false;//走到这里说明数据中没有,返回false
    }

4.indexOf——查找某个元素对应的位置

    // 查找某个元素对应的位置
    public int indexOf(int toFind) {
    	//遍历所有数据,找到返回下标
        for (int i = 0; i < size; i++) {
            if(array[i] == toFind) {
                return i;
            }
        }
        return -1;没找到返回-1
    }

5.get——获取 pos 位置的元素

此时,也要对pos位置的合法性进行判断,判断规则与add方法不同,
因为是获取已有数据,所以pos的位置最大只能为size-1。
也就是0 < = pos < size

    public int get(int pos) {
		//如果位置不合法,抛出异常
        if(pos < 0 || pos >= size) {
            throw new RuntimeException("输入位置不合法");
        }
        
        return array[pos];//位置合法,返回pos位置上的数据
    }

6.set——给 pos 位置的元素设为 value

与get方法相同,要判断pos位置是否合法。

    public void set(int pos,int value) {
        if(pos < 0 || pos >= size) {
            throw new RuntimeException("输入位置不合法");
        }
        array[pos] = value;
    }

7.remove——删除第一次出现的关键字key

    public void remove(int toRemove) {
        //遍历数据去找到toRemove
        for (int i = 0; i < size; i++) {

            if(array[i] == toRemove) {
                //找到后,依次用后面的数据覆盖前面的数据
                for (int j = i; j < size - 1; j++) {
                    array[i] = array[i+1];
                }
                size--;//更新数据个数
                return;//只删除首个toRemove
            }
        }
    }

8.size——获取顺序表长度

    // 获取顺序表长度
    public int size() {
        return size;
    }

9.clear——清空顺序表

    // 清空顺序表
    public void clear() {
        this.size = 0;
    }

10.disPlay——打印顺序表

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

二、java中提供的ArrayList

【说明】

  1. ArrayList是以泛型方式实现的,使用时必须要先实例化
  2. ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问
  3. ArrayList实现了Cloneable接口,表明ArrayList是可以clone的
  4. ArrayList实现了Serializable接口,表明ArrayList是支持序列化的
  5. 和Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择Vector或者CopyOnWriteArrayList
  6. ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表

1.ArrayList的构造方法

  1. 无参构造
    ArrayList()
	ArrayList<Integer> arrayList = new ArrayList<>();
	//构造一个空表

  1. 指定顺序表初始容量
    ArrayList(int initialCapacity)
    ArrayList<Integer> arrayList = new ArrayList<>(10);
    //构造一个初始容量为10的表

  1. 利用其他 Collection 构建 ArrayList
    ArrayList(Collection<? extends E> c)
    参数列表指的是传入的可以是一个继承了接口Collection且数据类型相同的其他类,顺序表,链表,栈,队列等等。
    public static void main(String[] args) {
        ArrayList<Integer> arrayList = new ArrayList<>(10);
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        arrayList.add(4);
        arrayList.add(5);
        arrayList.add(6);
        ArrayList<Integer> arrayList1 = new ArrayList<>(arrayList);
        for (int i = 0; i < arrayList1.size(); i++) {
            System.out.print(arrayList1.get(i) + " ");
        }

    }

arrayList继承了Collection接口
arrayList与arrayList1的存储数据类型相同,
因此可以直接将arrayList当作参数传入,
此时,arrayList1按顺序将arrayList中的所有数据都存储了

在这里插入图片描述


2.ArrayList类中的常用方法

    public static void main(String[] args) {
        ArrayList<Integer> arrayList = new ArrayList<>();

        //1.尾插法,将数据插入到顺序表末尾
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add(3);
        System.out.println("插入数据后:" + arrayList);

        //2.将数据插入到1位置
        arrayList.add(1,0);
        System.out.println("在下标1位置插入数据后:" + arrayList);

        //3.将ary中的所有数据按顺序尾插到arrayList中
        ArrayList<Integer> ary = new ArrayList<>();
        ary.add(1);
        ary.add(2);
        ary.add(3);
        arrayList.addAll(ary);
        System.out.println("将其他顺序表插入后:" + arrayList);


        //4.删除index位置的数据
        arrayList.remove(2);
        System.out.println("删除下标2位置的数据后:" + arrayList);

        //5.删除遇到的第一个 ‘1’
        arrayList.remove(new Integer(1));
        System.out.println("删除‘1’后:" + arrayList);
        //此处的‘1’指的是一个Object类及其子类,
        //此处如果输入基本类型int,那么会自动识别成index即 4.方法
        //ArrayList中存储的是Object类,
        //而插入时,输入的是基本类型,但是会自动给你装箱变为Integer类
        //所以该方法不能输入基本类型,应输入包装类或自定义类,还包括8. 9. 10.方法

        //两个remove构成了重载,传入的参数不同,执行结果也不同。

        //6.获取下标 3 位置元素
        int ret = arrayList.get(3);
        System.out.println("下标3位置的数据:" + ret);

        //7.将下标0位置的数据改为-1
        arrayList.set(0,-1);
        System.out.println("0下标改为-1后:" + arrayList);

        //8.判断 ‘1’ 是否在线性表中
        boolean flg = arrayList.contains(new Integer(1));
        System.out.println("判断是否存在1这个数据" + flg);

        //9.返回第一个 ‘1’ 所在下标
        int index = arrayList.indexOf(new Integer(1));
        System.out.println("第一个 ‘1’ 所在下标" + index);

        //10.返回最后一个 ‘1’ 的下标
        int lastIndex = arrayList.lastIndexOf(new Integer(1));
        System.out.println("最后一个 ‘1’ 所在下标" + lastIndex);

        //11.截取arraylist下标[1,5)位置的数据,返回的是一个List类的表
        List<Integer> list = arrayList.subList(1,5);
        System.out.print("截取到的表:");
        for (int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i) + " ");
        }
        System.out.println();

        //12.清空表
        arrayList.clear();
    }
  • 以上所有涉及到位置index的方法,输入的位置均都需要合法。

总结

以上就是今天要分享的数据结构开篇作《顺序表》的内容了,本文介绍了模拟实现的建议顺序表,以及ArrayList类的常用方法。

路漫漫,不止修身也养性。

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值