数据结构 之 顺序表 ArrayList (Java)

2024-03-05 1182阅读

温馨提示:这篇文章已超过385天没有更新,请注意相关的内容是否还可用!

目录

1.线性表:

2.顺序表

2.1 顺序表的使用:

2.1.1 构造方法:

2.1.2 顺序表的常用方法:

3. 模拟实现整体源码分享:


在该篇文章中,大概介绍了顺序表,以及模拟实现了顺序表中的常用方法;

在了解顺序表之前,我们需要去了解线性表:

1.线性表:

线性表是一种广泛应用的数据结构,是一个聚友n个相同特性的数据元素的有限序列;

常见的线性表有:顺序表(ArrayList),链表(LinkedList),栈(Stack),队列(Queue)...

线性表在逻辑上是线性结构,也就是一条直线,但是在物理结构上却不一定是连续的,线性表在存储数据时,通常以数组和链表的形式去存储。

2.顺序表

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储

ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表

数据结构 之 顺序表 ArrayList (Java)

根据顺序表的源码可知:

1. ArrayList继承于AbstractList,并且ArrayList是以泛型的方式实现的,使用的时候必须要先实例化;

2. ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问;

3. ArrayList实现了Cloneable接口,表明ArrayList是可以clone的;

4. ArrayList实现了Serializable接口,表明ArrayList是支持序列化的;

5. 和Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择Vector或者 CopyOnWriteArrayList;

2.1 顺序表的使用:

2.1.1 构造方法:

首先我们要认识顺序表的构造方法,顺序表中一共有三个构造方法:

源码如下:

数据结构 之 顺序表 ArrayList (Java)

数据结构 之 顺序表 ArrayList (Java)

数据结构 之 顺序表 ArrayList (Java)

这是不带参数的构造方法:默认数组为空数组;

数据结构 之 顺序表 ArrayList (Java)

这是带一个参数的构造方法:将顺序表的容量大小置为参数大小

数据结构 之 顺序表 ArrayList (Java)

这是参数为Collection的构造方法:利用其他的Collection去构建ArrayList;

2.1.2 顺序表的常用方法:

通过观察源码,我们发现,ArrayList的方法非常多,但在接下来的介绍和模拟实现的过程中,我只会介绍和模拟最常见的方法;

 首先我们先构建一个My_ArrayList类

数据结构 之 顺序表 ArrayList (Java)

  add 方法

数据结构 之 顺序表 ArrayList (Java)

add方法也就是我们常用的插入方法,源码对add方法进行了重载,在这里我们模拟实现add方法的其中一个重载方法。

模拟实现:

一般来说,在顺序表中插入元素,有两种插入方法,尾插和给定位置插入,(头插也就是给定位置为0的插入),由于顺序表是以数组的方式存储数据的,所以在插入之前,我们要判断一下,给定的位置是否合理,若不合理,则需要抛出异常,并且判断数组是否是满的,如果数组是满的,那我们就需要进行扩容;

大概的代码如下:

这是指定位置的add方法

数据结构 之 顺序表 ArrayList (Java)

数据结构 之 顺序表 ArrayList (Java)

数据结构 之 顺序表 ArrayList (Java)

数据结构 之 顺序表 ArrayList (Java)

指定位置的add方法写出来之后,那么头插和尾插就简单了;

头插即pos == 0, 尾插即pos == usedSize - 1;

get方法:

get方法有一个参数pos,就是获取pos下标的元素,写法也十分简单:

在获取该下标的元素之前,我们同样要对该下标进行是否合法判断,若不合法则抛出异常,合法则返回该下标所对应的元素;

数据结构 之 顺序表 ArrayList (Java)

set方法:

set方法有两个参数,一个是pos,也就是下标,另一个是value,是给定的值,作用是将pos位置的元素更新为value;

在更新数据之前,我们同样需要对pos位置进行合法性的判断,若不合法,则抛出异常,写法同样很简单:

数据结构 之 顺序表 ArrayList (Java)

  indexOf 方法:

该方法有一个参数toFind, 该方法的作用的找到toFind元素的下标并返回,若没有该元素则返回 -1;

数据结构 之 顺序表 ArrayList (Java)

  remove 方法:

remove方法有一个参数key, 作用是找到顺序表中的第一个key元素并将其删除;

在删除之前,我们需要判断顺序表是否为空,若为空,则抛出异常;

数据结构 之 顺序表 ArrayList (Java)

  contains 方法:

contains方法有一个参数toFind,作用是判断顺序表中是否包含toFind元素;

数据结构 之 顺序表 ArrayList (Java)

  clear 方法:

clear方法是将顺序表中的元素全部删除;

数据结构 之 顺序表 ArrayList (Java)

3. 模拟实现整体源码分享:

import java.util.Arrays;
public class MyArrayListIndexOutOfException extends RuntimeException{
    public MyArrayListIndexOutOfException() {
        super();
    }
    public  MyArrayListIndexOutOfException(String str) {
        super(str);
    }
}
public class MyArrayListEmptyException extends RuntimeException{
    public MyArrayListEmptyException() {
        super();
    }
    public MyArrayListEmptyException(String str) {
        super(str);
    }
}
public class My_ArrayList {
    public int[] elem;
    public int usedSize;//0
    //默认容量
    private static final int DEFAULT_SIZE = 10;
    public My_ArrayList() {
        this.elem = new int[DEFAULT_SIZE];
    }
    /**
     * 打印顺序表:
     *   根据usedSize判断即可
     */
    public void display() {
        //usedSize==0
        for (int i = 0; i  this.usedSize) {
            System.out.println("pos位置不合法");
            return false;
        }
        return true;//合法
    }
    // 在 pos 位置新增元素
    public void add(int pos, int data) {
        //判断下标是否是合法的,若不合法,则抛出异常
        if(!checkPosInAdd(pos)) {
            throw new MyArrayListIndexOutOfException("添加方法的pos不合理!");
        }
        //判断是否是满的,若是满的,则进行扩容(此处为二倍扩容)
        if (isFull()) {
            this.elem = Arrays.copyOf(this.elem,2*this.elem.length);
        }
        //挪数据,将pos位置及pos位置之前的数据向后移动,并将pos位置空出来存放data参数
        for (int i = this.usedSize-1; i >= pos ; i--) {
            this.elem[i+1] = this.elem[i];
        }
        //挪完了数据,在pos位置存放data参数
        this.elem[pos] = data;
        this.usedSize++;
    }
    // 判定是否包含某个元素
    public boolean contains(int toFind) {
        for (int i = 0; i = this.usedSize) {
            System.out.println("pos位置不合法");
            return false;
        }
        return true;//合法
    }
    // 获取 pos 位置的元素
    public int get(int pos) {
        if(!checkPosInGet(pos)) {
            throw new MyArrayListIndexOutOfException("获取pos下标时,位置不合法");
        }
        //不用写判断空不空 没有问题的
//        if(isEmpty()) {
//            throw new MyArrayListEmptyException("获取元素的时候,顺序表为空!");
//        }
        return this.elem[pos];
    }
    private boolean isEmpty() {
        return this.usedSize == 0;
    }
    // 给 pos 位置的元素设为【更新为】 value
    public void set(int pos, int value) {
        if(!checkPosInGet(pos)){
            throw new MyArrayListIndexOutOfException("更新pos下标的元素,位置不合法");
        }
        //如果合法 ,那么其实不用判断顺序表为空的状态了
//        if(isEmpty()) {
//            throw new MyArrayListEmptyException("顺序表为空!");
//        }
        //顺序表为满的情况也可以更新
        this.elem[pos] = value;
    }
    /**
     * 删除第一次出现的关键字key
     * @param key
     */
    public void remove(int key) {
        //判断顺序表是否为空,若为空,则抛出异常
        if(isEmpty()) {
            throw new MyArrayListEmptyException("顺序表为空,不能删除!");
        }
        //使用indexOf方法,找到key元素的下标
        int index = indexOf(key);
        //若没有key元素,则输出“不存在你要删除的数据”
        if(index == -1) {
            System.out.println("不存在你要删除的数据");
            return;
        }
        //用key位置的后面的所有元素往前依次移动一次,覆盖掉key元素
        for (int i = index; i  

以上就是顺序表的全部内容

制作不易,三连支持

谢谢!!!

以上的模拟实现代码未必是最优解,仅代表本人的思路,望多多理解,谢谢!!

最后送给大家一句话,同时也是对我自己的勉励:

不要因为没有掌声而放弃梦想!!!!!

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]