数据结构-ArrayList解析和实现代码

news2024/10/5 16:24:25

arrayList结构的实现是数组结构,数组没有扩容机制,arrayList的扩容机制采用的是复制数组,了解你会发现ArrayList虽然实现比较简单,但是设计还是很巧妙的。咱们先来简单实现下..

咱们看下定义的全局变量

1.默认初始化空间为10,也就是默认数组空间大小

2.定义个空元素

3.顶一个数组存储元素

4.数组长度

5.构造方法默认给个空元素

    // 默认初始化空间
    private static final int DEFAULT_CAPACITY = 10;
    // 空元素
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELMENTDATA = {};
    // ArrayList元素数组缓冲区
    transient Object[] elementData;
    // List 集合元素数量
    private int size;

    public ArrayList() {
        // 默认给个空的元素,当开始添加元素的时候在初始化长度
        this.elementData = DEFAULTCAPACITY_EMPTY_ELMENTDATA;
    }

1.添加元素

添加就是将数据存储到上边定义的elementData数组里,需要按数组下标一个个的排好存储,但是如果超出了默认的数组长度10怎么办?需要新开辟空间,把原数组原封不动的放回原有的位置,接下来看下代码。

第一次添加元素时

  1.1 size为0,minCapacity得到的就是1,因为数据都是空,所以minCapacity设置了默认值10

   1.2 10-0 肯定大于0,创建数组空间,那么当数组存储10条时这个minCapacity就是11,11-10大于0,需要扩容了还是运用了一个操作,这块设计的就很好

   1.3 当需要扩容时找到旧数组的长度,然后用旧数组的长度+旧数组长度除以2,也就是除了第一次扩容是10,第二次就是15。

    1.4 新要开辟的数字小于之前的minCapacity,newCapacity - minCapacity,那就把minCapacity赋值给newCapacity,在第一次存储数据就是这样,newCapacity=0,minCapacity=10,就需要赋值

    1.5 通过Arrays.copyof(数组,长度); 开辟空间,扩容也是如此

    1.6 然后存储数据,返回成功

第二次添加元素时

minCapacity=2,判断扩容2-10是小于0的,不扩容,直接存储返回数据

// 添加
    public boolean add(E e) {
        int minCapacity = size + 1;
        if (elementData == DEFAULTCAPACITY_EMPTY_ELMENTDATA) {
            minCapacity = DEFAULT_CAPACITY;
        }
        // 判断是否数组容量不足
        if (minCapacity - elementData.length > 0) {
            int oldCapacity = elementData.length;
            // 加原来数组长度+将原来数组长度除2
            int newCapacity = oldCapacity + (oldCapacity >> 1);
            // 扩展数据比原最小容量小就直接赋值minCapacity
            if (newCapacity - minCapacity < 0) {
                newCapacity = minCapacity;
            }
            // 进行复制原数组操作
            elementData = Arrays.copyOf(elementData, newCapacity);
        }
        // 存储数据
        elementData[size++] = e;
        return true;
    }

2.获取元素

获取元素非常简单,根据下标获取元素即可

    // 根据索引查询
    public E get(int index) {
        return (E) elementData[index];
    }

3.删除元素

删除元素需要考虑移动元素的情况,假如1-2-3-4,删除2以后数组就是134,3的下标就是1,而不是以前的2。

根据System.arraycopy进行解决移动数据问题,假如现有1-2-3-5-8数据,删除了3也就是小标2的数据,那么原数组的拷贝需要从index+1开始,也就是不拷贝3的元素,拷贝到目标元素还是elementData,从index位置也就是3的位置开始拷贝,拷贝几个数据呢,需要拷贝size-index-1,也就是说5-2-1=2,拷贝两个就是5和8到elementData,这样数组最后就剩1-2-5-8,其实就是挤出去的,是不是设计很巧妙,拷贝完后将长度减1,并把数组最后一个元素置为空


    public E remove(int index) {
        E e = get(index);
        // 总共拷贝多条数据
        int numMoved = size - index - 1;
        if (numMoved > 0) {
            // 把elementData元素进行拷贝,从index+1(就是当前要删除的下一个元素开始)
            // 拷贝到elementData元素,从index下标为止,赋值后所有的数据
            System.arraycopy(elementData, index + 1, elementData, index, numMoved);
        }
        elementData[--size] = null;
        return e;
    }

4.更新

更新则和获取一样,通过下标元素找到值直接赋当前值

    // 更新
    public boolean set(int index, E e) {
        elementData[index] = e;
        return true;
    }

全部代码

package linkedList;

import java.util.Arrays;
import java.util.List;

/**
 * @Author df
 * @Date 2022/11/20 15:16
 * @Version 1.0
 */
public class ArrayList<E> {
    // 默认初始化空间
    private static final int DEFAULT_CAPACITY = 10;
    // 空元素
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELMENTDATA = {};
    // ArrayList元素数组缓冲区
    transient Object[] elementData;
    // List 集合元素数量
    private int size;

    public ArrayList() {
        // 默认给个空的元素,当开始添加元素的时候在初始化长度
        this.elementData = DEFAULTCAPACITY_EMPTY_ELMENTDATA;
    }

    // 添加
    public boolean add(E e) {
        int minCapacity = size + 1;
        if (elementData == DEFAULTCAPACITY_EMPTY_ELMENTDATA) {
            minCapacity = DEFAULT_CAPACITY;
        }
        // 判断是否数组容量不足
        if (minCapacity - elementData.length > 0) {
            int oldCapacity = elementData.length;
            // 加原来数组长度+将原来数组长度除2
            int newCapacity = oldCapacity + (oldCapacity >> 1);
            // 扩展数据比原最小容量小就直接赋值minCapacity
            if (newCapacity - minCapacity < 0) {
                newCapacity = minCapacity;
            }
            // 进行复制原数组操作
            elementData = Arrays.copyOf(elementData, newCapacity);
        }
        // 存储数据
        elementData[size++] = e;
        return true;
    }

    // 根据索引查询
    public E get(int index) {
        return (E) elementData[index];
    }

    public E remove(int index) {
        E e = get(index);
        // 总共拷贝多条数据
        int numMoved = size - index - 1;
        if (numMoved > 0) {
            // 把elementData元素进行拷贝,从index+1(就是当前要删除的下一个元素开始)
            // 拷贝到elementData元素,从index下标为止,赋值后所有的数据
            System.arraycopy(elementData, index + 1, elementData, index, numMoved);
        }
        elementData[--size] = null;
        return e;
    }

    // 更新
    public boolean set(int index, E e) {
        elementData[index] = e;
        return true;
    }

    public void print() {
        for (Object o : elementData) {
            System.out.print("-" + o);
        }
        System.out.println("");
    }

    public static void main(String[] args) {
        List list = new java.util.ArrayList();
        list.add("1111");

        System.out.println("插入元素----");
        ArrayList arrayList = new ArrayList();
        arrayList.add("1");
        arrayList.add("2");
        arrayList.add("3");
        arrayList.add("5");
        arrayList.add("8");
        arrayList.print();

        System.out.println("获取元素----");
        System.out.println(arrayList.get(2));
        System.out.println("删除元素----");
        arrayList.remove(2);
        arrayList.print();
        System.out.println("更新元素----");
        arrayList.set(2, "3");
        arrayList.print();

    }
}

执行结果 

 

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

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

相关文章

docker 安装 Jenkins

一、Jenkins 安装 增加挂载目录和权限 # 增加挂载目录和权限mkdir /workspace/jenkins_homechown -R 1000:1000 /workspace/jenkins_home/创建容器 docker run --name jenkins -d \ -p 9999:8080 \ -p 8888:8888 \ -p 50000:50000 \ -v /workspace/jenkins_home:/var/jenkins…

[附源码]java毕业设计智慧教室预约

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

java检验mp4文件完整性的一个方法:使用ffmpeg

问题引入 最近笔者在写一个多线程下载视频文件的程序&#xff0c;打算让这个程序在我的空闲服务器上运行&#xff0c;但是几轮测试之后发现&#xff0c;有时候会存在下载的视频文件不完整的情况&#xff0c;这就导致了有些文件无法正常播放 问题排查 经过一周的排查后&#…

小白学流程引擎-FLowable(一) —FLowable是什么

小白学流程引擎-FLowable(一) | FLowable是什么 一、什么是流程引擎&#xff1f; 通俗的说&#xff0c;流程引擎就是多种业务对象在一起合作完成某件事情的步骤&#xff0c;把步骤变成计算机能理解的形式就是流程引擎。 流程引擎&#xff0c;用来驱动业务按照设定的固定流程…

《Kafka 源码实战》看完面试不慌!

Kafka 一开始是 LinkedIn 公司开发的消息队列&#xff0c;随着 Kafka 代码被贡献给 Apache 软件基金会后&#xff0c;就成功孵化成 Apache 顶级项目&#xff0c;世界上有越来越多的公司和个人开始使用 Kafka&#xff0c;所以 Kafka 使用的范围是很普遍的。 同时&#xff0c;值得…

vue实现文件上传压缩优化处理

vue js实现文件上传压缩优化处理 两种方法 &#xff1a; 第1种是借助canvas的封装的文件压缩上传第2种&#xff08;扩展方法&#xff09;使用compressorjs第三方插件实现 目录 vue js实现文件上传压缩优化处理 借助canvas的封装的文件压缩上传 1.新建imgUpload.js 2.全局引…

grafana变量使用

注&#xff1a;基于Grafana v8.3.6编写 1 添加变量 在dashboard界面点击setting&#xff0c;就能进入设置页面&#xff0c; 再点击Variables tab&#xff0c;就可以添加变量 比如我们添加一个系统架构的变量&#xff0c;用于区分Linux和Windows系统&#xff0c;通过node_una…

这可能是2022年把微服务讲的最全了:SpringBoot+Cloud+Docker

前言 最近几年&#xff0c;微服务可谓是大行其道。在业务模型不完善&#xff0c;超大规模流量的冲击的情况下&#xff0c;许多企业纷纷抛弃了传统的单体架构&#xff0c;拥抱微服务。这种模式具备独立开发、独立部署、可扩展性、可重用性的优点的同时&#xff0c;也带来这样一…

【云原生】K8S master节点更换IP以及master高可用故障模拟测试

文章目录一、前言二、配置 多个master 节点1&#xff09;节点信息1&#xff09;安装docker或containerd2&#xff09;安装kubeadm&#xff0c;kubelet和kubectl1、配置k8s yum源2、修改sandbox_image 镜像源3、配置containerd cgroup 驱动程序systemd4、开始安装kubeadm&#x…

SpringBoot SpringBoot 原理篇 1 自动配置 1.7 bean 的加载方式【五】

SpringBoot 【黑马程序员SpringBoot2全套视频教程&#xff0c;springboot零基础到项目实战&#xff08;spring boot2完整版&#xff09;】 SpringBoot 原理篇 文章目录SpringBootSpringBoot 原理篇1 自动配置1.7 bean 的加载方式【五】1.7.1 register1 自动配置 1.7 bean 的…

FAIRNESS IN MACHINE LEARNING: A SURVEY 阅读笔记

论文链接 刚读完一篇关于机器学习领域研究公平性的综述&#xff0c;这篇综述想必与其有许多共通之处&#xff0c;重合部分不再整理笔记&#xff0c;可详见上一篇论文的笔记&#xff1a; A Survey on Bias and Fairness in Machine Learning 阅读笔记_Catherine_he_ye的博客 S…

红队隧道加密之MSF流量加密(二)

前言 如今大多数企业的内网都部署了流量审计服务, 用来专门分析流量特征, 比如后门特征和行为特征 若直接使用Metasploit对内网进行横向渗透, 其产生的流量会很容易被内网防护工具检测出来, 因此需对流量进行加密来绕过检测 这里介绍使用OpenSSL对MSF流量进行加密 演示步骤 …

这么高颜值的Kubernetes管理工具Lens,难道还不能C位出道吗

一直使用官方的Kubernetes Dashboard来管理k8s&#xff0c;也算很友好的一款UI工具&#xff0c;但显示的资源不全、查看日志有限、时间久了要重要登陆&#xff0c;所以找了一款外观漂亮&#xff0c;用户体验很好的管理平台Lens。 2 特性与安装 2.1 特性 Lens的优势主要有&…

齐聚绿城 | 锦江都城酒店聚焦中高端酒店投资新方向

提起广西&#xff0c;不少人能想到 “桂林山水甲天下”的桂林&#xff0c;亦或因一碗螺蛳粉闻名全国的柳州。又或荣登《国家地理》的涠洲岛。但在你不知晓的时候&#xff0c;南宁这座城在静静的等你发掘。南宁——南疆安宁&#xff0c;是山环水绕的“绿城”&#xff0c;也是北回…

windows系统cmake生成动态库无lib文件解决方法

作为cmake初学者&#xff0c;在windows系统下使用cmake生成c动态库时出现了下图所示问题&#xff0c;是关于lib文件。找了一圈&#xff0c;也没发现生成有lib文件。 在google上查&#xff0c;才发现windows系统下动态库生成lib文件&#xff0c;还需要添加以下命令&#xff1a; …

java 同步锁synchronized 解决线程共享数据重复操作问题

我们先来写一个买票程序 我们先创建一个包 在包下创建两个类 customException 线程类 负责编写抢票的主要逻辑 参考代码如下 public class customException implements Runnable {private int tickets 100;public void run () {while (tickets > 0){if(tickets > 0) {…

【语音增强】多维谱自适应小波语音信号去噪【含Matlab源码 1972期】

⛄一、自适应小波语音信号去噪 1 引言 语音信号在传输过程中&#xff0c;容易受到环境噪声和其他语音的干扰&#xff0c;降低了语音通信质量&#xff0c;影响了语音处理系统工作。所以&#xff0c;语音的净化处理技术&#xff0c;在现代语音通信和数字音频广播系统中起到愈来愈…

特殊的转义字符—— \b 退格字符 ASCII 08

引入 我们在写 C 语言题目时&#xff0c;经常会碰见这样的输出 11 123 1236 123410如果用循环的话&#xff0c;这个加号是个大问题&#xff0c;如果直接用 printf("%d")&#xff0c;最后会多一个加号&#xff0c;用 printf("%d") 则前面会多一个加号。想…

Qt编写视频监控管理平台(支持海康/大华/宇视/华为/天地伟业/H264/H265等)

一、前言 海康大华等厂家自己的客户端软件&#xff0c;基本上都是支持自家的设备&#xff0c;不支持其他家的摄像机和硬盘录像机&#xff0c;并不是因为技术上做不到&#xff0c;这些大厂要实现支持兼容其他的家的&#xff08;他们家的服务端或者收费的都是支持其他家的&#…

写个rpc调用,试试自己了解多少

什么是rpc rpc即是远程过程调用&#xff0c;简单来说就是调用其他服务的接口像调用自己的本地方法一样&#xff0c;通常我们的调用的时候不需要关心调用过程和底层的通信即可实现调用其他的服务&#xff1b; 大概流程就是服务模块双方都会向注册中心注册自己的服务&#xff0c…