List、ArrayList与顺序表的介绍(数据结构系列3)

news2025/1/8 11:05:30

目录

前言:

1.List

1.1什么是List

1.2List的使用

2.ArrayList

2.1线性表

2.2ArrayList的方法

2.3ArrayList的模拟实现

2.4ArrayList的使用

2.5ArrayList的三种遍历方式

2.5.1for循环遍历

2.5.2for-each遍历

2.5.3使用迭代器遍历

结束语:


前言:

1.List

1.1什么是List

在集合框架中List是一个接口,继承自Collection,如下图所示:

 其中Collection也是一个接口,该接口中规范了后序容器中常用的一些方法,如下图所示:

 Lterable也是一个接口,表示实现该接口的类是可以逐个元素进行遍历的,具体如下所示:

1.2List的使用

在数据结构的角度来看,List就是一个线性表,即n个具有相同类型元素的有限序列,在该序列上可以执行增删改查以及变量等操作。需要注意的是List是一个接口,并不能直接用来实例化。如果要使用的话,必须去实例化List的实现类,在集合框架中,ArrayList和LinkedList都实现了List接口。

那么接下来我们来具体看一下什么是ArrayList以及带大家去了解一下ArrayList中的一些方法。

2.ArrayList

2.1线性表

在数据结构中存在一中结构叫线性结构,其中线性结构中又包含了顺序结构和链式结构,那么接下来我先带着大家一起来了解一下什么是顺序结构。

顺序表:

顺序表使用一段物理地址连续的存储空间单元依次存储数据元素的线性结构,一般情况下都是采用数组存储,在数组上完成增删改查操作。其实通俗的将顺序表就是一个数组,将数据以顺序的方式存储起来。

2.2ArrayList的方法

那么我可以现在idea上查看一下ArrayList具体都有哪些方法。

那么接下来我们来自己实现一下这些方法。 

2.3ArrayList的模拟实现

代码实现如下所示,具体的方法解释也在代码中,详见代码。
MyArrayList代码:

import java.util.Arrays;

public class MyArrayList {
    //顺序表不适合频繁的删除数据
    public int[] elem;//默认为NULL
    public int usedSize;//存储了多少个有效数据
    public static final int DEFAULT_SIZE = 5;//给定一个默认值
    public MyArrayList() {
        this.elem = new int[DEFAULT_SIZE];//进行开辟空间初始化
    }

    //打印数组
    public void display() {
        for (int i = 0; i < this.usedSize; i++) {
            System.out.print(this.elem[i] + " ");
        }
    }

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

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

    //查找某个元素对应的位置
    public int indexOf(int toFind) {
        for (int i = 0; i < this.usedSize; i++) {
            if (this.elem[i] == toFind) {
                return i;
            }
        }
        return -1;
    }

    //新增元素,默认在数组最后新增
    public void add(int data) {
        if (isFull()) {
            resize();
        }
        this.elem[this.usedSize] = data;
        this.usedSize++;
    }

    //判断是否为满
    public boolean isFull() {
        if (this.usedSize >= this.elem.length) {
            return true;
        }
        return false;
    }

    //扩容
    private void resize() {
        this.elem = Arrays.copyOf(this.elem, 2 * this.elem.length);
    }

    //在pos位置新增元素,与上述的add方法构成了重载
    //时间复杂度O(1)
    public void add(int pos, int data) {
        checkAddIndex(pos);
        for (int i = this.usedSize - 1; i >= pos ; i--) {
            this.elem[i + 1] = this.elem[i];
        }
        this.elem[pos] = data;
        this.usedSize++;
    }
    //检查位置的合法性
    private void checkAddIndex(int pos) {
        if (pos < 0 || pos > this.usedSize) {
            throw new IndexOutInException("该位置不合法!");
        }
    }
    //获取pos位置的值
    public int get(int pos) {
        checkGetIndex(pos);
        for (int i = 0; i < this.usedSize; i++) {
            if (this.elem[i] == this.elem[pos]) {
                return this.elem[i];
            }
        }
        return -1;
    }
    //判断获取元素的时候位置的合法性
    private void checkGetIndex(int pos) {
        if (pos < 0 || pos > this.usedSize) {
            throw new IndexOutInException("pos 位置不合法!");
        }
    }

    //给pos位置的元素设置为value
    public void set(int pos, int value) {
        checkIndex(pos);
        this.elem[pos] = value;
    }

    //检查给pos位置的元素设置为value时位置的合法性
    private void checkIndex(int pos) {
        if (pos < 0 || pos > this.usedSize) {
            throw new IndexOutInException("该位置不合法!");
        }
    }

    //删除第一次出现的关键字key
    public void remove(int toRemove) {
        int ret = 0;
        for (int i = 0; i < this.usedSize; i++) {
            if (this.elem[i] == toRemove) {
                ret  = i;
            }
        }
        for (int i = ret; i < this.usedSize; i++) {
            this.elem[i] = this.elem[i + 1];
        }
        this.usedSize--;
    }

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

接口代码:

public class IndexOutInException extends RuntimeException{
    public IndexOutInException () {

    }
    public IndexOutInException (String msg) {
        super(msg);
    }
}

Test代码:

public class Test {
    public static void main(String[] args) {
        MyArrayList myArrayList = new MyArrayList();
        myArrayList.add(1);
        myArrayList.add(2);
        myArrayList.add(3);
        myArrayList.add(4);
        myArrayList.add(5);
        myArrayList.display();
        System.out.println();
        myArrayList.add(6);
        myArrayList.display();
        System.out.println();
        int ret = myArrayList.size();
        System.out.println(ret);
        boolean ret2 = myArrayList.contains(2);
        System.out.println(ret2);
        int ret3 = myArrayList.indexOf(3);
        System.out.println(ret3);
        myArrayList.add(1,99);
        myArrayList.display();
        System.out.println();
        int ret5 = myArrayList.get(1);
        System.out.println(ret5);
        myArrayList.set(1,33);
        myArrayList.display();
        System.out.println();
        myArrayList.remove(1);
        myArrayList.display();
        System.out.println();
        myArrayList.clear();
        myArrayList.display();
    }
}

结果截图:

2.4ArrayList的使用

虽然List是一个接口不可以实例化,但是我们可以根据ArrList来实现它的具体方法。

代码如下所示:

import java.util.ArrayList;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();//在<>中可以指定存储的类型
        list.add("hello");
        list.add(" world");
        list.add("!!!");
        System.out.println(list);//打印里面的元素
        System.out.println(list.size());//获取list中有多少个元素
        //获取和设置index位置上的元素,注意index必须是在[0,size)之间
        String  ret1 = list.get(1);
        System.out.println(ret1);
        list.set(2,"!");
        System.out.println(list);
        //在list位置上插入指定的元素
        list.add(1,"this");
        System.out.println(list);
        //删除指定位置上的元素
        list.remove(1);
        System.out.println(list);
        //检测list中是否包含指定元素
        boolean ret2 = list.contains("hello");
        System.out.println(ret2);
        //查找指定元素第一次出现的位置
        list.add("a");
        list.add("a");
        list.add("b");
        System.out.println(list);
        System.out.println(list.indexOf("a"));//查到就会返回该位置的下标
        //清除所有元素
        list.clear();
        System.out.println(list);
        System.out.println(list.size());
    }
}

结果下所示:

 

2.5ArrayList的三种遍历方式

2.5.1for循环遍历

代码如下所示:

import java.util.List;

public class Test1 {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        //使用for遍历
        for (int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i) + " ");
        }
    }
}

结果如下所示:

 

2.5.2for-each遍历

代码如下所示:

import java.util.ArrayList;
import java.util.List;

public class Test2 {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        for (Integer a:list) {
            System.out.print(a + " ");
        }
    }
}

 

结果如下所示:

2.5.3使用迭代器遍历

代码如下所示:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Test3 {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(3);
        list.add(4);
        list.add(5);
        list.add(6);
        Iterator<Integer> iterator = list.listIterator();//构造器
        while (iterator.hasNext()) {
            System.out.print(iterator.next() + " ");
        }
    }
}

结果如下所示:

 

结束语:

好了,这节有关于List和ArrayList的知识小编就分享到这里啦!后期小编会出有关于ArrayList的具体使用例子,继续关注小编,小编带你一起学会数据结构哦!希望对大家有所帮助,想要学习的同学记得关注小编和小编一起学习吧!如果文章中有任何错误也欢迎各位大佬及时为小编指点迷津(在此小编先谢过各位大佬啦!)

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

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

相关文章

分享88个JS焦点图代码,总有一款适合您

分享88个JS焦点图代码&#xff0c;总有一款适合您 88个JS焦点图代码下载链接&#xff1a;https://pan.baidu.com/s/1zfspX9OSsbAlL53fjiSCEw?pwdulz6 提取码&#xff1a;ulz6 Python采集代码下载链接&#xff1a;https://wwgn.lanzoul.com/iKGwb0kye3wj base_url "…

XGBoost

目录 1.XGBoost推导示意图 2.分裂节点算法 Weighted Quantile Sketch 3.对缺失值得处理 1.XGBoost推导示意图 XGBoost有两个很不错得典型算法&#xff0c;分别是用来进行分裂节点选择和缺失值处理 2.分裂节点算法 Weighted Quantile Sketch 对于特征切点点得选择&#xff…

怎么不让消息弹出?录屏弹窗怎么关

当我们对电脑屏幕进行录制时&#xff0c;时不时跳出的消息窗口和广告会影响我们录制的效果。怎样不让消息弹出&#xff1f;如何关闭录屏弹窗&#xff1f;使用“锁定窗口录制”模式&#xff0c;就能很好地解决这个问题。那有没有拥有“锁定窗口”录制模式的录屏工具&#xff1f;…

synchronized 关键字-监视器锁 monitor lock

1.代码示例&#xff1a; package thread3;import java.util.Scanner;public class Test2 {public static Object object new Object();public static void main(String[] args) throws InterruptedException {Thread thread1 new Thread(() -> {Scanner scanner new Sca…

盂县基本情况

寒假的活动报告&#xff0c;万物皆可CSDN&#xff0c;贴一下吧 盂县隶属于阳泉市&#xff0c;阳泉市是李彦宏和刘慈欣的家乡&#xff0c;阳泉市内有百度云计算中心 基本情况 盂县&#xff0c;隶属山西省阳泉市&#xff0c;地处山西省东部、太行山西麓&#xff0c;东与河北省平…

测试开发面经

操作系统 进程与线程 进程间通信方式 进程间的六种通信方式 管道消息队列共享内存信号量信号套接字 socket长连接和短连接 长连接与短连接的概念&#xff1a;前者是整个通讯过程&#xff0c;客户端和服务端只用一个Socket对象&#xff0c;长期保持Socket的连接&#xff1b…

Windows/VM虚拟机安装黑群晖6.1-----保证有效而且简单操作

1视频&#xff1a;Windows/VM虚拟机安装黑群晖教程_哔哩哔哩_bilibili2:网址&#xff1a;Synology Web Assistant3&#xff1a;重新打开群晖操作步骤1&#xff1a;按着视频下载好资源后&#xff0c;按照视频操作&#xff0c;途中修改地方&#xff08;两个情况选择其中一个&…

Docker系列(镜像原理)03

前言 镜像就是图中的集装箱&#xff0c;仓库就是超级码头&#xff0c;容器就是我们运行程序的地方。 从联合文件系统说起 Union文件系统(UnionFS )是一种分层、轻量级并且高性能的文件系统。它支持对文件系统的修改作为一次提交来一层层的叠加&#xff0c;同时可以将不同目录…

【游戏逆向】】游戏全屏捡物的分析实现

前言 在角色对战类中&#xff0c;拾取怪物掉落的装备是一项必备的工作&#xff0c;由于装备位置掉落的不确定性&#xff0c;玩家想要拾取离角色距离较远的装备需要一定的时间&#xff0c;这一段时间往往会影响游戏的评分或是玩家的心态&#xff0c;基于此&#xff0c;全屏捡物…

【Unity VR开发】结合VRTK4.0:键盘操作运动与旋转

前言&#xff1a; 当我们的手柄无发进行VR测试&#xff0c;或者想通过键盘进行验证&#xff0c;那么就用到了我们今天的一个功能&#xff1a;组合操作。组合操作允许更复杂的输入类型&#xff0c;我们将介绍如何使用布尔输入&#xff08;如键盘键&#xff09;来模拟模拟轴&…

Java中LinkedList增删改比ArrayList快吗?

在 Java 中&#xff0c;LinkedList 和 ArrayList 的性能是不同的&#xff0c;具体取决于你所需要的操作。 对于频繁的插入和删除操作&#xff0c;LinkedList 的性能通常更好&#xff0c;因为它使用了链表数据结构&#xff0c;只需更改节点的指针就可以在链表中插入或删除元素。…

剑指Offer 第26天 表示数值的字符串 Hard

表示数值的字符串_牛客题霸_牛客网 描述 请实现一个函数用来判断字符串str是否表示数值&#xff08;包括科学计数法的数字&#xff0c;小数和整数&#xff09;。 科学计数法的数字(按顺序&#xff09;可以分成以下几个部分: 1.若干空格 2.一个整数或者小数 3.&#xff08;可选&…

计算机组成原理第七章笔记记录

仅仅作为笔记记录,B站视频链接&#xff0c;若有错误请指出&#xff0c;谢谢 基本概念 演变过程 I/O系统基本组成 I/O软件 包括驱动程序、用户程序、管理程序、升级补丁等 下面的两种方式是用来实现CPU和I/O设备的信息交换的 I/O指令 CPU指令的一部分,由操作码,命令码,设备…

前端 基于 vue-simple-uploader 实现大文件断点续传和分片上传

文章目录一、前言二、后端部分新建Maven 项目后端pom.xml配置文件 application.ymlHttpStatus.javaAjaxResult.javaCommonConstant.javaWebConfig.javaCheckChunkVO.javaBackChunk.javaBackFileList.javaBackChunkMapper.javaBackFileListMapper.javaBackFileListMapper.xmlBac…

2023年rabbitMq面试题汇总4(7道)

一、如何保证消息的顺序性&#xff1f;1. 通过某种算法&#xff0c;将需要保持先后顺序的消息放到同⼀个消息队列中(kafka中就是partition,rabbitMq中就是queue)。然后只⽤⼀个消费者去消费该队列。2. 可以在消息体内添加全局有序标识来实现。二、使⽤RabbitMQ增加rest服务吞吐…

JVM调优几款好用的内存分析工具

对于高并发访问量的电商、物联网、金融、社交等系统来说&#xff0c;JVM内存优化是非常有必要的&#xff0c;可以提高系统的吞吐量和性能。通常调优的首选方式是减少FGC次数或者FGC时间&#xff0c;以避免系统过多地暂停。FGC达到理想值后&#xff0c;比如一天或者两天触发一次…

【Android -- 每日一问】现在 Android 怎么学?学什么?

不管在任何行业&#xff0c;任何岗位&#xff0c;初级技术人才总是供大于求&#xff1b;不管任何行业、岗位&#xff0c;技术过硬的也都是非常吃香的&#xff01; 这几年 Android 新技术的迭代明显加速了&#xff0c;有来自外部跨平台新物种的冲击&#xff0c;有去 Java 化的商…

Dropout的原理与细节?

1. 什么是Dropout? Dropout是通过使得每个神经元以一定的概率停止工作来接缓解过拟合问题。dropout(随机失活):dropout是通过遍历神经网络每一层的节点,然后通过对该层的神经网络设置一个keep_prob(节点保留概率),即该层的节点有keep_prob的概率被保留,keep_prob的取值范围…

YOLO-V1~V3经典物体检测算法介绍

大名鼎鼎的YOLO物体检测算法如今已经出现了V8版本&#xff0c;我们先来了解一下它前几代版本都做了什么吧。本篇文章介绍v1-v3&#xff0c;后续会继续更新。一、节深度学习经典检测方法概述1.1 检测任务中阶段的意义我们所学的深度学习经典检测方法 &#xff0c;有些是单阶段的…

windows无法访问指定设备路径或文件怎么办?2个解决方案

有时候Win10电脑打不开程序或文件&#xff0c;windows无法访问指定设备路径或文件该怎么办&#xff1f;原因是什么呢&#xff1f;一般导致这种情况的出现&#xff0c;大多是因为我们的电脑缺乏相应的查看权限&#xff0c;我们只需要通过赋予权限就可以解决这个难题了。 操作环境…