手把手教你如何实现List——ArrayList

news/2024/5/20 9:06:51 标签: list, 数据结构, 顺序表

目录

前言:

 线性表

顺序表

  接口的实现

一. 打印顺序表

二.新增元素,默认在数组最后新增

三.在 pos 位置新增元素 

四.判定是否包含某个元素

 五. 查找某个元素对应的位置

 六.获取 pos 位置的元素

七.给 pos 位置的元素设为 value 

八.删除第一次出现的关键字key 

九.获取顺序表长度

十.清空顺序表 

ArrayList的遍历

ArrayList的问题及思考

前言:

什么是List?

在集合框架中,List是一个接口,继承自Collection。

站在数据结构的角度来看,List就是一个线性表,即n个具有相同类型元素的有限序列,在该序列上可以执行增删改查以及变量等操作。 

List中提供了好的方法,具体如下:

 

注意:List是个接口,并不能直接用来实例化。
如果要使用,必须去实例化List的实现类。在集合框架中,ArrayListLinkedList都实现了List接口。

本篇我们开始 ArrayList的学习


 线性表

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列...

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


顺序表

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

  接口的实现

先初始化数组 

有效数字现在为useSize 

模拟实现接口里面的所有的功能  也基本上就学会了顺序表的所有功能

实现在MyArrayList这个类中重写

一. 打印顺序表

 打印顺序表比较简单,知道它的userSize,遍历一遍就可以

public void display() {
        for (int i = 0; i < useSize ; i++) {
            System.out.print(elem[i] + "");
        }
        System.out.println();
    }

二.新增元素,默认在数组最后新增

思路: 直接找到userSize位置,直接赋值就行 有效数组userSize为4

假如我们需要添加5,直接在下标为4的位置上赋值

添加完userSize++

考虑问题要全,如果数组满了,我们需要给它扩容已被才可以添加 

所有得先判断是否数组满了,如果满了先扩容再添加

代码实现:

public void add(int data) {
        //判断
        if(useSize == 5) {
            elem = Arrays.copyOf(elem,elem.length*2);
        }
        //添加
        elem[useSize] = data;
        useSize++;
    }

 效果:


三.在 pos 位置新增元素 

 

在1下标添加11 

应该把1下标后面的元素往后面移动  从userSzie-1下标开始向右移动 

并且得先从最右边的元素开始移动

最后userSize++;

考虑情况:  

另外pos下标值不能小于0或者大于usersize

代码实现: 

 public void add(int pos, int data) {
        //先检查是否数组满了吗?
        if(useSize == 5) {
            elem = Arrays.copyOf(elem,elem.length*2);
        }
        // 判断pos是否合法
        if(pos < 0 || pos > useSize) {
            //抛出异常
            throw new PosException("pos未知不合法" + pos);
        }
        for (int i = useSize - 1; i >= pos ; i--) {
            elem[i+1] = elem[i];
        }
        elem[pos] = data;
        useSize++;
    }

 


四.判定是否包含某个元素

 

遍历整个数组,再判断

代码实现:  

   public boolean contains(int toFind) {
        for (int i = 0; i < useSize; i++) {
            if(elem[i] == toFind) {
                return true;
            }
        }
        return false;
    }

 五. 查找某个元素对应的位置

代码实现:  

   public int indexOf(int toFind) {
        for (int i = 0; i < useSize; i++) {
            if(elem[i] == toFind) {
                return i;
            }
        }
        return -1;
    }


 六.获取 pos 位置的元素

 

这里的pos不能等于userSize了,否则越界了 

代码实现:  

   public int get(int pos) {
         判断pos是否合法
        if(pos < 0 || pos >= useSize) {
            //抛出异常
            throw new PosException("pos未知不合法" + pos);
        }
        return elem[pos];
    }

七.给 pos 位置的元素设为 value 

代码实现:  

 public void set(int pos, int value) {
        // 判断pos是否合法
        if(pos < 0 || pos > useSize) {
            //抛出异常
            throw new PosException("pos未知不合法" + pos);
        }
        elem[pos] = value;
    }


八.删除第一次出现的关键字key 

 

先判断顺序表是否为空 空的不可以删除的

删除结束userSize-- 

 代码实现:  

    public void remove(int toRemove) {
        if(useSize == 0){
           throw new EmptyException("顺序表为空");
        }
        //获取toRemove下标
        int index = indexOf(toRemove);
        for (int i = index; i < useSize - 1 ; i++) {
            elem[i] = elem[i+1];
        }
        useSize--;
    }

九.获取顺序表长度

 public int size() {
        return useSize;
    }

十.清空顺序表 

 public void clear() {
        useSize = 0;
    }

 以上基本上就是顺序表所有的基本操作 


ArrayList的遍历

一:直接打印

 二:for循环遍历

三. for each遍历

 四.使用迭代器


ArrayList的问题及思考

1. ArrayList底层使用连续的空间,任意位置插入或删除元素时,需要将该位置后序元素整体往前或者往后搬移,故时间复杂度为O(N)
2. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。
3. 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。

当在ArrayList任意位置插入或者删除元素时,就需要将后序元素整体往前或者往后
搬移,时间复杂度为O(n),效率比较低,因此ArrayList不适合做任意位置插入和删除比较多的场景。

接下来我们会进行 LinkedList(链表)的学习


http://www.niftyadmin.cn/n/5223432.html

相关文章

Django回顾2

目录 一.HTTP 1.URL介绍 2.格式&#xff1a; 3.补充&#xff1a; 二.web框架 1.什么是框架 2.什么是web框架 3.wsgi协议 基于wsgi协议的web服务器&#xff1a; 4.协议是怎么规定的 三.Django 1.MVC与MTV模型&#xff08;所有框架其实都遵循MVC架构&#xff09; 2.…

aikit 2023 3D与机械臂结合!

引言 今天我们主要了解3D摄像头是如何跟机械臂应用相结合的。我们最近准备推出一款新的机械臂套装AI Kit 2023 3D&#xff0c;熟悉我们的老用户应该知道&#xff0c;我们之前的AI Kit 2023套装使用的是2D摄像头。 随着技术进步&#xff0c;市场需求和领域的扩大&#xff0c;2D的…

Unity中的资源——Asset

Unity中的资源——Asset 文章目录 Unity中的资源——Asset什么是Asset什么是ObjectsUnity文件、文件引用、Meta详解Meta文件详解——Unity GUID/ FileID/ InstanceID系统总结参考文章 什么是Asset Asset理解为Unity能够识别的文件。即Projects窗口里看到的单个文件&#xff08…

麒麟操作系统光盘救援模式

麒麟操作系统光盘救援模式 Kylin V4 桌面版&#xff1a; 启动主机后&#xff0c;插入系统光盘&#xff0c;在 BIOS 启动项里设置成从光盘启动后保存退出重启主机。 稍等片刻就会到启动菜单选项&#xff0c;到启动菜单界面后选择第一项试用银河麒麟操作系统而不安 装&#xff…

java设计模式 开闭原则

开闭原则&#xff08;Open-Closed Principle&#xff0c;OCP&#xff09;是面向对象设计中的一个重要原则&#xff0c;它指导着我们如何设计和组织代码&#xff0c;以便使系统在扩展性和可维护性方面更加优秀。 开闭原则的定义是&#xff1a;软件实体&#xff08;类、模块、函数…

React 之 airbnb - 项目实战

一、开发前言 1. 规范 2. 创建项目 node -v > 18.0.0 npm -v > 8.6.0 create-react-app star-airbnb 3. 项目基本配置 配置jsconfig.json {"compilerOptions": {"target": "es5","module": "esnext","ba…

​序列类型 --- list, tuple, range​

目录 通用序列操作 不可变序列类型 可变序列类型 列表 元组 range 对象 有三种基本序列类型&#xff1a;list, tuple 和 range 对象。 为处理 二进制数据 和 文本字符串 而特别定制的附加序列类型会在专门的小节中描述。 通用序列操作 大多数序列类型&#xff0c;包括可…

贪心算法(新坑)

贪心入门 概述&#xff1a; 贪心算法是一种在每一步选择中都采取当前最优解的策略&#xff0c;希望最终能够得到全局最优解的算法。简单来说&#xff0c;它会不断地做出局部最优的选择&#xff0c;相信通过这种选择最终能够达到全局最优。 举个例子来说明。假设你要从一个迷…