数据结构-ArrayLIst-一起探索顺序表的底层实现

各位看官早安午安晚安呀

如果您觉得这篇文章对您有帮助的话

欢迎您一键三连,小编尽全力做到更好
欢迎您分享给更多人哦

大家好,我们今天来学习java数据结构的第一章ArrayList(顺序表)

1.ArrayList的概念

那小伙伴就要问了线性表到底是什么呢?
线性表 linear list n 个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列...(我们后续都会进行讲解)
线性表首先是一个序列,也就是说,元素之间是有顺序的,如果元素存在多个,那么第一个元素无前驱。最后一个元素无后驱。其他每个元素都必须有一个前驱和后驱
例如:
usedSize这个变量是非常重要的,我们的增删查改都要用到

1.2ArrayList的模拟实现

import java.util.Arrays;

public class MyArrayList {

    private int []elem;//用来存放数据
    private int usedSize;//非常重要,代表当前顺序表当中的有效数据个数

    private static final int DEFAULT_SIZE = 2;

    public MyArrayList() {
        this.elem = new int[DEFAULT_SIZE];
    }
    public MyArrayList(int initCapacity){
        this.elem = new int[initCapacity];
    }

    // 新增元素,默认在数组最后新增
    public void add(int data) {
        if(elem.length == usedSize){
            elem = Arrays.copyOf(elem,elem.length*2);
        }
        elem[usedSize] = data;
        this.usedSize++;//一定不要忘记加
    }
    // 在 pos 位置新增元素
    public void add(int pos, int data) {//只要带pos的都要进行检查
        if(checkPos(pos) ==false ){
            return;
        }
            if (elem.length == usedSize) {
            elem = Arrays.copyOf(elem, elem.length * 2);
        }
            //下面这种写法就错误了,导致pos后面的值都是pos位置的值
        /*for (int i = pos; i < usedSize -1; i++) {
            elem[i+1] = elem[i];
        }*/
        //应该从后往前
        for (int i = usedSize-1 ; i >= pos; i--) {
            elem[i+1] = elem[i];
        }
        elem[pos] = data;
        usedSize++;
    }

    /*public void delete(int pos){
        if(checkPos(pos) == false)
        if(this.usedSize == 0){
            System.out.println("数组里面没有元素了");
            return;
        }
        for (int i = 0; i < usedSize - 1; i++) {
            elem[i] = elem[i+1];
        }
    }
*/

    // 判定是否包含某个元素
    public boolean contains(int toFind) {//啥意思
        for (int i = 0; i < usedSize; i++) {
            if(elem[i] == toFind ) //这里是int类型,所以你能够直接比较,其他类型的话,要重写equals方法
                return true;
        }
        return false;
    }

    // 查找某个元素对应的位置
    public int indexOf(int toFind) {
        for (int i = 0; i < usedSize; i++) {
            if(elem[i] == toFind)
            return i;
        }
        System.out.println("没有你要找的值");
        return -1;
    }

    public boolean checkPos(int pos){
        if( pos < 0 || pos >= usedSize){
            System.out.println("下标错误");
            return false;
        }
        return true;
    }
    // 获取 pos 位置的元素
    public int get(int pos) {

        if(checkPos(pos) == false){
            return -1;
        }
        return elem[pos];
    }

    // 给 pos 位置的元素设为 value
    public void set(int pos, int value) {
        if(checkPos(pos) == false){
            return;
        }
        elem[pos] = value;
    }

    //删除第一次出现的关键字key
    public void remove(int data) {
        int index = this.indexOf(data);
        if(index == -1){
            System.out.println("没有这个数据");
            return;
        }
        for (int i = data; i < usedSize - 1; i++) {
            elem[i] = elem[i+1];
        }
       //如果是引用类型的话: elem[index] = null;
        this.usedSize--;

    }

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

    // 清空顺序表
    public void clear() {
        this.usedSize = 0;
        //但是如果是引用类型的话
/*
        for (int i = 0; i < usedSize; i++) {
            elem[i] = null;
            记得全部置为空
            引用类型的话,删除也要置为null
        }
*/
    }

    // 打印顺序表,注意:该方法并不是顺序表中的方法,为了方便看测试结果给出的
    public void display() {
        for (int i = 0; i < usedSize; i++) {
            System.out.print(this.elem[i] + " ");
        }
    }
}

目前我们自己实现了顺序表这种结构,以后用到的时候,Java已经为我们提供好了

ArrayList(就是一个普通的类实现了List接口)

(自己看一下方法)(ArrayLIst里面的方法,底层方法)(我们可以看出来ArrsyList底层的数组我们在实例化对象时也是默认长度为我们的常量值,有效元素个数非常重要,我们增加删除元素等方法都要用的)

2:构造方法

我们要了解一个类首先要了解他的构造方法

ArrayList<E>中的E就表示列表中存储的元素的类型

ArrayList

2.1:构造方法一,三

       ArrayList<Integer> list = new ArrayList<>();   这种能用的方法更多
       List<Integer> list = new ArrayList<>();    一般我们用这一种,向上转型,动态绑定的等等,你俩用哪个主要看自己业务场景
       ArrayList<Integer> list = new ArrayList<>(15)

我们可以看到默认数组长度是10,前面源码图解上有

2.2:构造方法二

然后我把list1指定的类型换成Integer就解决问题了!

大家也可以看到我明明对于list3只add了一次但是,打印出来的值却把list1数组里面的内容也拷贝过来了(拷贝在外面构造方法那一步就完成了)

2.3:ArrayList常见操作

public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(1,4);
        System.out.println(list);//到这里是【1,4,2,3】

        list.remove(1);//这两个老是搞混,这个是删除1小标的值
        list.remove(new Integer(1));//要删除1这个元素的值一定要用这种方法,因为这个参数是Object类型的
        System.out.println(list);//到这里是【2,3】

        // list.get(2);//这里会报一个数组越界异常,就是用来和UsedSize比较

        list.add(99);
        list.add(100);
        list.add(101);
        boolean isFalse = list.contains(new Integer(100));//这里最好用Integer类型的
        System.out.println(isFalse);//true

        List<Integer> list1 = list.subList(1,4);//左闭右开
        System.out.println(list1);

        list.set(1,200);
        System.out.println(list);
        System.out.println(list1);
        //list1得到的是从list数组里面的引用,只要改变其中一个元素的值,另一个也会改变

        list.clear();
        System.out.println(list);
        //全部清除
    }

2.4:ArrayList的三种遍历

ArrayList 可以使用三方方式遍历: for 循环 + 下标、 foreach 、使用迭代器
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遍历
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i) + " ");
}
System.out.println();
// 借助foreach遍历
for (Integer integer : list) {
System.out.print(integer + " ");
}
System.out.println();

//迭代器
Iterator<Integer> it = list.listIterator();
//ListIterator<Integer> it = list.listIterator();也可以
//ListIterator是Iterator的子类
while(it.hasNext()){
System.out.print(it.next() + " ");
}
System.out.println();
}
注意:
1. ArrayList 最长使用的遍历方式是: for 循环 + 下标 以及 foreach
2. 迭代器是设计模式的一种,后续博客我会继续讲解

2.5:ArrayList的扩容机制的缺陷

ArrayList是一个动态类型的顺序表,即:在插入元素的过程中会自动扩容。以下是ArrayList源码中扩容方式
总结
1. 检测是否真正需要扩容,如果是调用 grow 准备扩容
2. 预估需要库容的大小
初步预估按照 1.5 倍大小扩容 ,如果用户所需大小超过预估1.5 倍大小,则按照用户所需大小扩容
真正扩容之前检测是否能扩容成功,防止太大导致扩容失败
3. 使用 copyOf 进行扩容

3:杨辉三角

力扣杨辉三角

实现:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Test {
    public static void main(String[] args) {
        int num = 5;
        List<Integer> row = new ArrayList<>();
        List<List<Integer>> ret = new ArrayList<>();
        row.add(1);
        ret.add(row);
        for (int i = 1; i < num; i++) {
            List<Integer> curRow1 = new ArrayList<>();
            curRow1.add(1);//每行的第一个元素都是1

            List<Integer> previousRow = ret.get(i - 1);

            for (int j = 1; j < i; j++) {
                Integer x = previousRow.get(j) + previousRow.get(j - 1);
                curRow1.add(x);

            }
            curRow1.add(1);//每行的最后一个元素也都是1

            ret.add(curRow1);//把这一行的数组加进去
        }
        for (List<Integer>list:ret   //遍历数组
             ) {
            System.out.println(list);
        }
        System.out.println("============================");
        Iterator<List <Integer>> it = ret.listIterator();//使用迭代器遍历数组
//ListIterator<Integer> it = list.listIterator();也可以
//ListIterator是Iterator的子类
        while(it.hasNext()){
            System.out.print(it.next() + " ");
            System.out.println();
        }

    }
    }

上述就是数据结构-ArrayLIst-数组的深入包装 的全部内容了,能看到这里相信您一定对小编的文章有了一定的认可,数据结构的出现让我们对于数据的组织的利用有了更加方便的使用~~

有什么问题欢迎各位大佬指出
欢迎各位大佬评论区留言修正

您的支持就是我最大的动力​​​!!!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

RabbitMQ(四)

SpringBoot整合RabbitMQ SpringBoot整合1、生产者工程①创建module②配置POM③YAML④主启动类⑤测试程序 2、消费者工程①创建module②配置POM③YAML文件内配置&#xff1a; ④主启动类⑤监听器 3、RabbitListener注解属性对比①bindings属性②queues属性 SpringBoot整合 1、生…

初始Java4

目录 一.继承 1.定义&#xff1a; 2.继承的语法&#xff1a; 3.子类访问父类 4.子类构造方法 5.super与this 6.继承方法 7.final关键字 &#xff08;1&#xff09;.变量不变 &#xff08;2&#xff09;.方法不变 &#xff08;3&#xff09;.类不可继承 8.继承与组合…

极限竞速 地平线5“d3dx12_43.dll”文件丢失或错误导致游戏运行异常如何解决?windows系统DLL文件修复方法

d3dx12_43.dll是存放在windows系统中的一个重要dll文件&#xff0c;缺少它可能会造成部分软件不能正常运行。当你的电脑弹出提示“无法找到d3dx12_43.dll”或“计算机缺少d3dx12_43.dll”等错误问题&#xff0c;请不用担心&#xff0c;我们将深入解析DLL文件错误的成因&#xf…

Leecode刷题C语言之超过阈值的最小操作数②

执行结果:通过 执行用时和内存消耗如下&#xff1a; // 最小堆的节点结构体 typedef struct {long long* heap;int size;int capacity; } MinHeap;// 初始化最小堆 MinHeap* createMinHeap(int capacity) {MinHeap* minHeap (MinHeap*)malloc(sizeof(MinHeap));minHeap->s…

[Qt]常用控件介绍-按钮类控件-QPushButton、QRedioButton、QCheckBox、QToolButton控件

目录 1.QPushButton按钮 介绍 属性 Demo&#xff1a;键盘方向键控制人物移动 2.Redio Button按钮 属性 clicked、pressed、released、toggled区别 单选按钮的分组 Demo&#xff1a;点餐小程序 3.CheckBox按钮 属性 Demo&#xff1a;获取今天的形成计划 4.ToolBu…

寒假第一次牛客周赛 Round 76回顾

AC数&#xff1a;2&#xff08;A、C&#xff09; B 思路&#xff1a; 等价于求&#xff1a; 数量最多的字符 #include<stdio.h> int main() {int n,num;int a[26]{0};//用于存储字母 a 到 z 的出现次数。scanf("%d",&n);char s[n];scanf("%s",s)…

StyleGaussian: Instant 3D Style Transferwith Gaussian Splatting 论文解读

目录 一、概述 二、相关工作 1、辐射场 2、3D编辑 3、风格迁移 三、StyleGaussian 1、特征嵌入 2、风格迁移 3、解码 四、实验 1、不同backbone下的量化和定性指标 2、解码器设计上的测试 3、内容损失平衡 4、风格平滑插值 一、概述 提出了StyleGaussian&#x…

基于django实现类似ebay的电子商务系统全英文

完整源码项目包获取→点击文章末尾名片&#xff01;

win32汇编环境,窗口程序中组合框的应用举例

;运行效果 ;win32汇编环境,窗口程序中组合框的应用举例 ;比如在窗口程序中生成组合框&#xff0c;增加子项&#xff0c;删除某项&#xff0c;取得指定项内容等 ;直接抄进RadAsm可编译运行。重点部分加备注。 ;以下是ASM文件 ;>>>>>>>>>>>>…

Docker 镜像制作原理 做一个自己的docker镜像

一.手动制作镜像 启动容器进入容器定制基于容器生成镜像 1.启动容器 启动容器之前我们首先要有一个镜像&#xff0c;这个镜像可以是从docker拉取&#xff0c;例如&#xff1a;现在pull一个ubuntu镜像到本机。 docker pull ubuntu:22.04 我们接下来可以基于这个容器进行容器…

微信小程序获取openid

2025年1月15日&#xff1a; 1、现在云服务器上安装nodejs&#xff0c;然后写个get接口&#xff1a; const express require(express); const app express();app.get(/getOpenid,(req,res)>{res.send("success"); })app.listen(3000,()>{console.log(server…

ASP.NET Core - 配置系统之配置添加

ASP.NET Core - 配置系统之配置添加 2. 配置添加 2. 配置添加 配置系统可以读取到配置文件中的信息&#xff0c;那必然有某个地方可以将配置文件添加到配置系统中。之前的文章中讲到 ASP.NET Core 入口文件中&#xff0c;builder(WebApplicationBuilder 对象) 中有一个 Config…

C#中通道(Channels)的应用之(生产者-消费者模式)

一.生产者-消费者模式概述 生产者-消费者模式是一种经典的设计模式&#xff0c;它将数据的生成&#xff08;生产者&#xff09;和处理&#xff08;消费者&#xff09;分离到不同的模块或线程中。这种模式的核心在于一个共享的缓冲区&#xff0c;生产者将数据放入缓冲区&#x…

ArcSegment绘制及计算

ArcSegment绘制及计算 给定起始点、终止点和 bulge 值计算弧线中心点和半径&#xff0c;绘制ArcSegment。 import math def calculate_arc_center_and_radius(x1, y1, x2, y2, bulge):angle4*math.atan(bulge)# 计算弦中点mid_x (x1 x2) / 2mid_y (y1 y2) / 2# 计算弦长的…

【高可用自动化体系】自动化体系

架构设计的愿景就是高可用、高性能、高扩展、高效率。为了实现架构设计四高愿景&#xff0c;需要实现自动化系统目标&#xff1a; 标准化。 流程自助化。 可视化&#xff1a;可观测系统各项指标、包括全链路跟踪。 自动化&#xff1a;ci/cd 自动化部署。 精细化&#xff1a…

FakeLocation 1599 | 内部旧版

前言:FakeLocation又更新了,在某安上面看见一些&#xff0c;大概问题就是地图没了&#xff0c;然后有更难搞了 任务一 我们先去看看地图是怎么个事情 这里用的是百度地图就没有了哈 高德地图是有的 任务二 null 选择成功了&#xff0c;虽然是null 任务三 地图位置 虽然不显示了…

初识算法和数据结构P1:保姆级图文详解

文章目录 前言1、算法例子1.1、查字典&#xff08;二分查找算法&#xff09;1.2、整理扑克&#xff08;插入排序算法&#xff09;1.3、货币找零&#xff08;贪心算法&#xff09; 2、算法与数据结构2.1、算法定义2.2、数据结构定义2.3、数据结构与算法的关系2.4、独立于编程语言…

2025年华数杯国际赛B题论文首发+代码开源 数据分享+代码运行教学

176项指标数据库 任意组合 千种组合方式 14页纯图 无水印可视化 63页无附录正文 3万字 1、为了方便大家阅读&#xff0c;全文使用中文进行描述&#xff0c;最终版本需自行翻译为英文。 2、文中图形、结论文字描述均为ai写作&#xff0c;可自行将自己的结果发给ai&#xff0c…

CSS的小知识

一、子选择器 (>) 让 CSS 样式只作用于子级和孙级元素&#xff0c;而不影响其他元素 有>是只对其子级有效&#xff0c;子选择器只会影响直接的子级元素&#xff0c;而不会影响更深层次的孙级元素 无>时是对子级、孙级、曾孙级等所有后代都有效

【经管数据】ZF数字采购采购明细数据(2015.3-2024.3)

一、数据来源&#xff1a; 原始数据来源为ZF采购网。数据涵盖了自2015年3月至2024年3月的ZF数字采购合同明细&#xff0c;反映了数字化转型在政府采购中的应用情况。 二、参考文献&#xff1a; [1] 申志轩, 祝树金, 文茜, 等. ZF数字采购与企业数字化转型[J]. 数量经济技术经济…