Java-数据结构-ArrayLis与线性表 (๑╹◡╹)ノ“““

news2024/9/23 13:18:11

目录:

一、List的简单的介绍:

二、线性表:

三、顺序表:

1、基本代码:

2、操作代码:

display()方法:

 add(int data)方法:

add(int pos,int data)方法:

contains(int toFind)方法:

indexOf(int toFind)方法:

get(int pos)方法:

set(int pos,int value)方法:

remove(int toRemove)方法:

size()方法:

clear()方法:

3、整体代码:

四、ArrayList简介:

五、ArrayList的使用:

 1、ArrayList的构造方法:

2、ArrayList的常见操作:

 add方法:

remove方法:

get(int index)方法: 

set(int index,E element)方法:

clear()方法:

contains(Object o)方法:

indexOf(Object o)方法:

lastIndexOf(Object o)方法:

 3、ArrayList的遍历:

总结:


一、List的简单的介绍:

  在我们了解 List 之前呢,我们要先看一个图片:

            我们可以看到这个图片的最左边呢就是我们List,这个List继承了 Collection 接口,Collection接口又继承了 Iterable,接口,所以我们的 List 接口就有了这两个接口的所有方法。

      在我们站在数据结构的角度来看呢,List 接口就是一个线性表,就是n个具有相同类型的元素的有限序列 ,在这个序列上可以进行增删查改的操作。

     注意我们的List是一个接口,不能实例化,要是使用的话,只能去实例化List的实现类。


二、线性表:

    常见的线性表为:顺序表、链表、栈、队列....

    对于线性表我们从逻辑上来说呢,其是线性结构,相当于是连续的一条直线,线性表在存储时候呢,通常以数组和链式结构来存储的。


三、顺序表:

     我们呢先来介绍线性表中的顺序表。我们来看看:

      顺序表呢,是使用一段物理地址连续的存储单元依次存储数据,一般情况下呢,我们使用数组进行存储,在数组上进行对元素的增删查改操作。

      这次能我们就是用数组来进行对数据的增删查改操作,在我们使用数组的时候呢,数组自带的方法不能满足我们的使用,这时候呢我们就自己定义一个类,让这个类来进行对方法的实现,以便于我们使用。

   那么接下来我们自己定义一个类,来进行对数组的增删查改等操作。 

我们来看看它的代码的每一步的实现:

1、基本代码:

    我们的类里里面用的是数组,所以我们要在类中定义一个数组:

由上面的图可知并且我们要使用构造方法来初始化数组:

       对于类的基本成员就结束了,接下来我们就差操作方法了,接下来看我们来看看,对于操作方法我们可以定义一个接口,便于我们管理:

      那么我们如果我们的数组长度不够了,我们想要改变其数组容量的话,要怎么办?那我们是不是可以把其长度定义成成员变量,使其进行改变:

     这里我们还有一个需要注意的点就是,我们这个类是实现了IList这个接口的,所以我们可以向上转型来调用方法:

  Ok,我们对于这个顺序表的基本的都已经写完了,接下来我们就开始一一实现这里的方法了


2、操作代码:

display()方法:

     打印顺序表。

     这个是非常简单的,就是对数组的遍历,我们再一一打印出来,我们来看看代码的实现:

      这个代码呢,是有一些问题的,我们用的是数组的长度,但是呢对于数组是不是可能不是每一个下标都放数据了,所以呢,我们只需要有效的数据就可以了,而且当我们有效的数据很小而我们的数组长度很大,是不是就浪费时间了呢?

     所以这里哦我们呢要用有效的数组长度:

我们调用一下代码,看看会不会报错:

我们来对比下,当我们使用数组长度的时候会输出什么呢


 add(int data)方法:

       新增元素,默认在数组的最后添加。在写代码之前我们先来看个图:

   是不是看到这个图片,觉得对于add代码是不是非常简单呢?

      是不是有人这样写的呢?

      那你想的太简单了︿( ̄︶ ̄)︿,如果我们添加数据,要是满了怎么办呢?所以不是很简单的,那么这个正确代码就是:

我们可以看到,代码执行之后是没有问题的。


add(int pos,int data)方法:

         和add(int data)构成重载方法,这个是在指定的位置放入数据,我们来看看它的原理: 我们来看看代码是怎样实现的:

我们来看看其代码运行的结果会不会报错:

我们可以看到没有异常发生,我们再看看当我们pos不合法会输出什么:


contains(int toFind)方法:

     查找和 toFind 这个数据相等的元素,有就返回true,没有就返回false。这个方法就是非常简单的了,就是遍历一次数组就可以了,我们来看看图:

 接下来我们来看看,这个方法的代码的实现:

我们来执行一下看看:

我们可以看到没有任何的问题


indexOf(int toFind)方法:

      这个方法和上面的方法是类似的,这个是返回其toFind的下标这个位置,所以我们的代码都差不多的。


get(int pos)方法:

         我们返回这个 pos 位置的下标的值,这个代码我们乍一看是不是觉得很简单呢?那你看对了,这个代码很简单,但是我们需要谨慎,我们要在这个代码执行执行之前呢,要查找两个方面是否有异常:


1、pos位置不能 < 0 或者不能 >= usedSize这个有效数组长度。
2、我们要看看我们的顺序表也就是数组是否为空

我们来看代码:

我们执行一下看看有没有问题:


set(int pos,int value)方法:

       这个方法和上面的方法是类似的,我们也是需要判断两次异常,才能执行代码。 

我们直接看代码和执行结果:


remove(int toRemove)方法:

       这个方法呢,是删除这个第一次出现的这个toRemove这个值

 我们先来看看代码的实现:

我们可以看到我们的代码是没有问题的。


size()方法:

    获得数组的有效长度,这个代码是非常简单的。我们来看:

 


clear()方法:

       这个方法也是很简单的,我们对于这些代码是不是都是对于有效长度来说的,所以当我们把有效数组长度设置为0时呢,我们是不是就把顺序表清空了呢? 所以这个是非常简单的:

对于这样的clear方法只能处理一些基本的数据类型,我们正常的写法呢,应该是:

     但是为什么报错呢,因为我们现在是基本数据类型,不涉及到内存的泄露,直接把有效长度赋值为0,就可以了。


我们来看一下整体的代码是什么样的:

3、整体代码:

package list;

public interface IList {
    // 打印顺序表,注意:该方法并不是顺序表中的方法,为了方便看测试结果给出的
    void display();
    // 新增元素,默认在数组最后新增
    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();

}
package list;
import java.util.Arrays;

public class MyArrayList implements IList{
    public int[] array;
    public int usedSize;//数组的有效的个数
    //默认的容量,长度不变的
    public static final int DEFAULT_SIZE = 10;

    public MyArrayList() {
        this.array = new int[DEFAULT_SIZE];//长度为十,默认初始化值为0
    }

    @Override
    public void display() {
        // 打印顺序表
        for (int i = 0; i < this.usedSize; i++) {
            System.out.print(array[i] + " ");
        }
        System.out.println("");
    }

    @Override
    public void add(int data) {
        // 新增元素,默认在数组最后新增
        if (isFull()) {
            //满了,不能放数据了,我们要进行扩容
            Expansion();
        }
        //进行添加数据的操作
        this.array[this.usedSize] = data;
        this.usedSize++;
    }
    //对于判满这个操作,我们在别的方法中也会使用
    //所以我们可以单独创建一个方法
    public boolean isFull() {
        //判满
        return this.usedSize == DEFAULT_SIZE;
    }
    private void Expansion() {
        //扩容操作,我们不想让别的类调用这个方法,我们只想在自己的类中调用
        this.array = Arrays.copyOf(this.array,
                2*this.array.length);
        //我们一般按照2倍或者1.5倍进行扩容
    }
    private void checkPos(int pos) throws PosIsNotlegally{
        if (pos < 0 || pos > usedSize) {
            throw new PosIsNotlegally("Pos位置不合法");
        }
    }
    @Override
    public void add(int pos, int data) {
        // 在 pos 位置新增元素
        try{
            checkPos(pos);//判断pos这个位置合不合法

            if (isFull()) {
                Expansion();
            }
            int end = this.usedSize;
            while(pos != end) {
                this.array[end] = this.array[end - 1];
                end--;
            }
            this.array[pos] = data;
            this.usedSize++;
        }catch(PosIsNotlegally e) {
            System.out.println("输入的Pos位置不合法");
            e.printStackTrace();
        }
    }

    @Override
    public boolean contains(int toFind) {
        // 判定是否包含某个元素
        for (int i = 0; i < this.usedSize; i++) {
            if (this.array[i] == toFind) {
                return true;
            }
        }
        return false;
    }

    @Override
    public int indexOf(int toFind) {
        // 查找某个元素对应的位置
        for (int i = 0; i < this.usedSize; i++) {
            if (this.array[i] == toFind) {
                return i;
            }
        }
        return -1;
    }
    private void checkPos2(int pos) throws PosIsNotlegally{
        if (pos < 0 || pos >= usedSize) {
            throw new PosIsNotlegally("Pos的位置不合法");
        }
    }
    @Override
    public int get(int pos) {
        // 获取 pos 位置的元素
        try {
            //判断是否出现异常
            checkPos2(pos);
            checkEmpty();
            //没有异常的话,直接返回pos下标的值
            return this.array[pos];
        }catch (PosIsNotlegally e) {
            System.out.println("pos的位置不合法");
            e.printStackTrace();
        }catch (EmptyException e) {
            System.out.println("顺序表为空");
            e.printStackTrace();
        }
        return -1;
    }
    private boolean isEmpty() {
        return usedSize == 0;
    }
    private void checkEmpty() throws EmptyException{
        if (isEmpty()) {
            throw new EmptyException("顺序表为空");
        }
    }
    @Override
    public void set(int pos, int value) {
        // 给 pos 位置的元素设为 value
        try {
            //这个也要判断异常
            checkPos2(pos);
            checkEmpty();
            //没有异常给pos位置赋值
            this.array[pos] = value;
        }catch (PosIsNotlegally e) {
            System.out.println("pos位置不合法");
            e.printStackTrace();
        }catch (EmptyException e) {
            System.out.println("顺序表为空");
            e.printStackTrace();
        }
    }

    @Override
    public void remove(int toRemove) {
        //删除第一次出现的关键字toRemove
        try{
            checkEmpty();
            int pos = indexOf(toRemove);
            if (pos == -1) {
                return;
            }
            for (int i = pos; i < usedSize - 1; i++) {
                array[i] = array[i + 1];
            }
            usedSize--;
        }catch (EmptyException e) {
            System.out.println("顺序表为空");
            e.printStackTrace();
        }
    }

    @Override
    public int size() {
        // 获取顺序表长度
        return this.usedSize;
    }

    @Override
    public void clear() {
        // 清空顺序表
//        for (int i = 0; i < usedSize; i++) {
//            array[i] = null;
//        }
        usedSize = 0;
    }
}
package list;

public class PosIsNotlegally extends RuntimeException{
    public PosIsNotlegally() {

    }

    public PosIsNotlegally(String message) {
        super(message);
    }
}
package list;

public class EmptyException extends RuntimeException{
    public EmptyException() {

    }

    public EmptyException(String message) {
        super(message);
    }
}

四、ArrayList简介:

           上面的呢,是我们用Java自己实现的 ArrayList 类,但是呢,对于Java来说呢,不像C语言,Java里面是有 ArrayList 的,不像C语言只能自己实现。

           但是呢,我们自己定义的MyArrayList这个类和编译器自带的 ArrayList 这个类是大同小异的。

            但是呢,在我们使用编译器里面自带的ArrayList这个类的时候我们有一些需要注意的地方:

注意:

1、ArrayList是以泛型方式实现的,在使用时必须要进行初始化。

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

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

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

对于Java自带的顺序表ArrayList来说,遍历顺序表呢就是直接打印就可以了。


五、ArrayList的使用:

 1、ArrayList的构造方法:

      对于我们想要是用ArrayList呢,我们是不是要先创建对象啊,所以我们来看看对于Java里自带的ArrayList的构造方法是什么样的:

  对于Java自带的构造方法呢,我们有三种构造方法:

1、无参构造:

2、有参构造:

     创建一个自定的参数的顺序表。

3、传表来构造:

 对于都可以传入什么值,我们来看看这个构造方法的源代码:

    这里是要实现了Collection这个接口, 我们这个 ?是通配符,我们后面介绍,这里的 ?是E或者是E的子类


2、ArrayList的常见操作:

 add方法:

1、add(E e)

          相当于我们自己写的add方法,也是在尾部插入。

2、add(int index,E element)

           在index位置插入element这个值。

3、addAll(Collection < ? extends E > c)

           将c中的元素全部进行尾插操作。

remove方法:

  

1、remove(int index):

        删除index下标的的元素。

2、remove(Object o)方法:

           删除数据o

get(int index)方法: 

       获得index位置的数据

     这个方法和我们自己实现的是差不多的,这里我们就不实现了

set(int index,E element)方法:

         将index下标的数据设置为element

clear()方法:

          清空

contains(Object o)方法:

        判断o是否在顺序表中

indexOf(Object o)方法:

        返回第一个o所出现的下标

lastIndexOf(Object o)方法:

         返回最后一个o的下标。

这些方法呢,和我们自己实现的都差不多,这里我就不在重复实现了。

subList(int fromIndex,int toIndex)方法:

            截取部分list。

当然除了这些方法呢,我们ArrayList还有方法,这些我们在使用的时候就可以去查一查 


 3、ArrayList的遍历:

1、我们可以直接使用打印顺序表,来进行打印:

2、for循环输出:

3、for-each循环遍历:

4、使用迭代器来进行遍历:

 


总结:

      OK,我们关于Java中自带的 ArrayList 的方法就已经简单的介绍完事了,这次的博客呢,也到这里结束了,下次我们要写几个关于ArrayList的题,让我们期待下次的见面,再见,拜拜~~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2090613.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大模型企业应用落地系列》基于大模型的对话式推荐系统》对话推荐系统技术架构

注&#xff1a;此文章内容均节选自充电了么创始人&#xff0c;CEO兼CTO陈敬雷老师的新书《自然语言处理原理与实战》&#xff08;人工智能科学与技术丛书&#xff09;【陈敬雷编著】【清华大学出版社】 文章目录 大模型企业应用落地系列全貌基于大模型的对话式推荐系统》技术架…

SpringWeb后端开发-登录认证

Author&#xff1a;Dawn_T17&#x1f965; 目录 登录功能 基础登录 登录校验 一、会话技术 1.基于 Cookie 和 Session 的传统会话技术(传统) 2.基于 Token 的会话技术&#xff08;如 JWT&#xff09;(主流)​ JWT 二、过滤器&#xff08;Filter&#xff09; 具体代…

《JavaEE进阶》----1.<JavaEE进阶可以学到什么>

本篇博客会讲到 一、JavaEE进阶学习内容&#xff1a; 1.框架的学习&#xff1a;Spring、Spring Boot、Spring MVC、MyBatis 2.大项目实践 3.源码阅读 二、JavaEE简介 B/S架构web开发流程 web前端开发&#xff08;了解&#xff09; web后端开发&#xff08;重点&#xff09; 三、…

properties文件提示未引用

问题描述 以前用的好好的项目,今天突然打开就发现idea不识别spring配置信息显示未引用,如果config代码中引入的配置却可以高亮显示,然后输入spring相关的配置,文件是没有提示的。经过研究发现是spring相关的插件被关闭了。效果如下 解决方法 启用三个插件spring Boot,Sp…

Idea发布springboot项目无法识别到webapp下面的静态资源

问题&#xff1a; Idea发布springboot项目无法识别到webapp下面的静态资源 访问报错404 解决办法&#xff1a; 修改之后重新构建&#xff0c;访问成功

Web3开发与安全:6个月高效学习路径

学习计划概览 总时长&#xff1a;6个月每周学习时间&#xff1a;10-15小时目标&#xff1a;掌握 Solidity 智能合约开发&#xff0c;并具备基本的智能合约安全审计能力。 第一阶段&#xff1a;基础准备&#xff08;第1-2周&#xff09; 1. 区块链基础&#xff08;1周&#x…

workman和GateWay学习笔记

前言 workman支持Udp GateWay是基于workman的二次封装&#xff0c;更适合长链接场景 windows安装workman composer create-project workerman/webman windows运行workman cd webman php windows.php windows访问 http://ip地址:8787 将workman引入thinkphp框架理念

4000字三合一!Stata、SPSS、MATLAB实现多元线性回归详解!

参加数学建模的小伙伴要注意了&#xff1a;多元线性回归几乎是所有分析方式里面最核心、最常用、最全面的模型&#xff0c;博主本科大致参加了10次数模&#xff0c;还有一次正大杯市场调研赛&#xff0c;其中获得拿得出手的奖有9次&#xff0c;有5次都用到了多元线性回归——至…

用Python在PDF文档中创建动作

PDF格式因其跨平台兼容性和丰富的功能集而成为许多行业中的首选文件格式。其中&#xff0c;PDF中的动作&#xff08;Action&#xff09; 功能尤为突出&#xff0c;它允许开发者嵌入交互式元素&#xff0c;如链接、按钮或是更复杂的脚本&#xff0c;从而显著提升文档的互动性和功…

c++vscode多文件实现通讯录管理系统

cvscode多文件实现通讯录管理系统 作为c入门级别的实战项目&#xff0c;此通讯管理系统项目不仅仅是对c入门阶段学习成果的检验&#xff0c;也是对c基础知识的回顾&#xff0c;体会c在实战制作中的思路,是入门c单文件实现通讯录系统的改进 一、多文件通讯录管理系统简介 系统需…

JAVA—多线程

关于线程以及多线程的学习&#xff0c;包括创建和常用方法还有解决线程安全的措施&#xff0c;最后学习线程池和了解并发和并行&#xff0c;对于悲观锁和乐观锁的部分没有学习 目录 1.线程概述 2.多线程的创建 &#xff08;1&#xff09;继承Thread类 &#xff08;2&#…

【GPT】基于GPT_API_free做一个自己的gpt

最终效果 项目背景 秉持能免费就绝不花钱的原则&#xff0c;基于github项目GPT_API_free获取的gpt apikey。下面是简单的代码 import json import os import requestsopenai_url os.getenv("openaiproxy") openai_apikey os.getenv("openaikey") # 初始…

[图解]SysML和EA建模住宅安全系统-活动作为块

1 00:00:00,210 --> 00:00:04,360 下一个步骤是识别潜在的失效 2 00:00:06,850 --> 00:00:11,150 这里它是用一个块定义图来表达的 3 00:00:12,150 --> 00:00:16,790 图17.21&#xff0c;失效模式识别和因果依赖 4 00:00:19,110 --> 00:00:22,400 但是这个块定义…

【AutoX.js】定时器 Timers

文章目录 原文&#xff1a;https://blog.c12th.cn/archives/36.html定时器 Timers笔记实例 最后 原文&#xff1a;https://blog.c12th.cn/archives/36.html 定时器 Timers 笔记 JavaScript Date 参考手册 时间戳 //当前时间戳 log(Math.round(new Date() / 1000));当前星期 …

C语言小tip之函数递归

hello&#xff0c;各位小伙伴们今天我们来学习一下函数递归。 什么是函数递归呢&#xff1f;简单来说就是函数自己来调用自己。函数递归的主要思想是把大事化小&#xff0c;递归包含两层方面&#xff1a;1、递推 2、回归 在使用函数递归的时候要注意包含两个限制条件&#…

SCI英文期刊发表流程

目录 一、撰写初稿二、预审三、英文查重四、Cover letter和Highlights五、英文语法待续 一、撰写初稿 英文好的话应该直接写英文&#xff0c;因为中英文的写法不一样。 而且在这一步把格式修改好&#xff0c;初稿的最终版 二、预审 可以让同学、老师帮看论文&#xff0c;或者…

[Algorithm][综合训练][字符编码][最少的完全平方数][游游的字母串]详细讲解

目录 1.字符编码1.题目链接2.算法原理详解 && 代码实现 2.最少的完全平方数1.题目链接2.算法原理详解 && 代码实现 3.游游的字母串1.题目链接2.算法思路详解 && 代码实现 1.字符编码 1.题目链接 字符编码 2.算法原理详解 && 代码实现 解法&…

Carla自动驾驶仿真十:Carlaviz三维可视化平台搭建

文章目录 前言一、环境准备1、docker安装2、websocket-client安装3、carlaviz代码下载 二、carlaviz使用1、打开carla客户端2、输入启动命令3、进入carlaviz4、修改manual_control.py脚本5、运行manual_control.py脚本6、运行carlaviz官方脚本&#xff08;推荐&#xff09; 前言…

数据库之心:MySQL 探索(一)mysql的安装和基本介绍

欢迎来到我们的MySQL博客&#xff01;在这里&#xff0c;我们将深入探讨MySQL数据库系统的各个方面&#xff0c;包括基础知识、优化技巧、实践案例以及最新的行业趋势。 目录 前言 什么是数据库&#xff1f; 数据库产品 MySQL安装 解压 配置 添加环境变量 初始化MySQL …

计算机毕业设计PySpark+Scrapy高考推荐系统 高考志愿填报推荐系统 高考爬虫 协同过滤推荐算法 Vue.js Django Hadoop 大数据毕设

目  录 第1章 绪论 1.1 研究背景 1.2 国内外现状 1.2.1 国外研究现状 1.2.2 国内研究现状 1.3 主要研究内容 1.4 论文框架结构 第2章 相关开发技术与理论 2.1 前端技术 1&#xff0e;Vue框架技术 2&#xff0e;Element-Plus 2.2 后端技术 1&#xff0e…