Java ArrayList底层方法的实现深度解析

 更新时间:2025年10月30日 16:01:03   作者:User_芊芊君子  
ArrayList是Java集合框架中List接口的动态数组实现,可以方便的存储和操作数据,这篇文章是进行ArrayList的一个自我实现,让我们从底层更深度地理解ArrayList(顺序表),感兴趣的朋友跟随小编一起看看吧

【前言】

ArrayList是Java集合框架中List接口的动态数组实现,可以方便的存储和操作数据。它提供了一系列方法,便于我们进行增删查改,这篇文章是进行ArrayList的一个自我实现,让我们从底层更深度地理解ArrayList(顺序表)

一、 定义ArrayList类

arr : 创建一个整型数组,用来存储数据; usedSize : 有效数据,也就是真实的元素个数;
DEFAULT_CAPACITY:默认数组容量
MyArrayList():构造方法,初始化数组长度为默认的容量

public class MyArrayList implements IList{
    private int[] arr;//存储数据
    private int usedSize;//有效数据个数
    public static final int DEFAULT_CAPACITY = 10;//默认数组容量
    public MyArrayList(){
        this.arr = new int[DEFAULT_CAPACITY];
    }

二、常见方法实现

ArrayList的常见方法如下:

1.add(int data):新增元素,添加在数组后面

 public void add(int data) {
        //判断顺序表是否满了
        if (isFull()) {
            //扩容
            grow();
        }
        //存储
        this.arr[this.usedSize] = data;
        this.usedSize++;
    }
    public boolean isFull(){
        return this.usedSize == this.arr.length;
    }
    public void grow(){
        this.arr = Arrays.copyOf(this.arr,2*this.arr.length);
    }

添加元素时,要先检查数组是否已满(isFull() 通过比较数组的长度和元素个数),如果满了,就要进行扩容grow(),这里是copy两倍的数组容量,然后再进行存储

2.add(int pos, int data):再pos位置添加元素

public void add(int pos, int data) {
        //检查是不是满的
        if(isFull()){
            grow();
        }
        checkPos(pos,"add方法执行的时候pos位置不合法");
            //判断是不是放在usedSize位置
            if(pos == usedSize){
                arr[pos] = data;
                usedSize++;
                return;
            }
            //如果放在前面,就要移动数据
            for (int i = usedSize-1; i >= pos; i++) {
                arr[i+1] = arr[i];
            }
            arr[pos] = data;
            usedSize++;
    }
    private void checkPosAdd(int pos,String msg) {
        if (pos < 0 || pos > usedSize) {
            throw new PosIllegalityException(msg);
        }
    }

还是先要检查容量是否已满isFull(),满了就要进行扩容grow(),然后添加时,要先检查pos位置是否合法,如上图,pos < 0 || pos > usedSize就是不合法的,在这个范围则会抛出我们自定义的PosIllegalityException异常,正常情况下进行添加:将pos位置及后面的元素统统向后移动一个位置,为要添加的元素腾出位置,然后有效数据usedSize++

3.contains(int toFind):判断是否包含某个元素

public boolean contains(int toFind) {
        for (int i = 0; i < this.usedSize; i++) {
            if(arr[i] == toFind){
                return true;
            }
        }
        return false;
    }

使用for循环遍历整个数组,if语句判断当前元素是否是你要找的元素toFind,是返回true,不是返回false

4.indexOf(int toFind):查找某个元素对应的位置

public int indexOf(int toFind) {
        for (int i = 0; i < this.usedSize; i++) {
            if(arr[i] == toFind){
                return i;
            }
        }
        return -1;
    }

同理:使用for循环遍历整个数组,if语句判断当前元素是否是你要找的元素toFind,是返回对应元素的下标i,不是返回-1

5.get(int pos):获取pos位置的元素

public int get(int pos) {
        if(isEmpty()){
            throw new EmptyListException("当前顺序表为空");
        }
        checkPos(pos,"get方法的pos位置不合法");
        return arr[pos];
    }
    private void checkPos(int pos,String msg){
        if (pos<0 || pos >= usedSize){
            throw new PosIllegalityException(msg);
        }
    }
    public boolean isEmpty(){
        return usedSize == 0;
    }

获取元素,先检查pos位置是否为空isEmpty(),如果为空,抛出我们的自定义异常EmptyListException,然后检查pos位置是否合法pos<0 || pos >= usedSize这个范围就是不合法的,抛出我们的自定义异常PosIllegalityException,最后就可以返回pos位置的元素

6.set(int pos, int value):给pos位置的元素设为value

public void set(int pos, int value) {
        if(isEmpty()){
            throw new EmptyListException("当前顺序表为空");
        }
        checkPos(pos,"set方法执行的时候pos位置不合法"+pos);
        arr[pos] = value;
    }

替换时要先检查是否为空isEmpty(),为空抛出自定义异常EmptyListException,不为空检查pos位置是否合法,最后将给定的值替换指定的数组元素

7.remove(int toRemove):删除第⼀次出现的关键字key

public void remove(int toRemove) {
        if(isEmpty()){
            throw new EmptyListException("当前顺序表为空");
        }
        //查找要删除数据的下标
        int index = indexOf(toRemove);
        if(index == -1){
            System.out.println("没有你要删除的数据");
            return;
        }
        for (int i = index; i < usedSize-1; i++) {
            arr[i] = arr[i+1];
        }
        usedSize--;
    }
     //arr[usedSize] = null;如果是引用类型,需要手动置空

还是先检查是否为空,然后可以通过indexOf(toRemove)查找要删除的元素,如果index == -1,则没有你要删除的元素,如果有,进行覆盖删除,让后面的元素逐一向前移动一个位置直到你要,直到覆盖掉你要删除的元素,最后将有效元素usedSize–

8.size():获取顺序表⻓度

public int size() {
        return this.usedSize;
    }

9.clear():清空顺序表

public void clear(){
        for (int i = 0; i < this.usedSize; i++) {
            arr[i] = 0;
        }
        usedSize = 0;
    }

三、总结

这篇文章只是从深度的实现了一下ArrayList提供的一系列方法,以便于更好地去理解和使用ArrayList,让我们认识到了,数据结构的学习和使用,要考虑到所有方面,对我们的逻辑思维能力要求很高,同样也会提高我们这方面的能力,相关的其他内容后面会详细道来

到此这篇关于Java ArrayList底层方法的自我实现的文章就介绍到这了,更多相关Java ArrayList底层方法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 深入理解Spring AOP

    深入理解Spring AOP

    这篇文章主要介绍了深入理解Spring AOP,详细的介绍了spring aop的具体实现与理论
    2017-01-01
  • Springboot有效防止XSS攻击的几种方法

    Springboot有效防止XSS攻击的几种方法

    本文介绍了在SpringBoot项目中防止XSS攻击的多种方法,包括输入验证和过滤、输出编码、使用安全框架、使用模板引擎的自动转义功能以及设置安全HTTP头等,感兴趣的可以了解一下
    2024-12-12
  • mybatis example如何自动生成代码 排序语句

    mybatis example如何自动生成代码 排序语句

    这篇文章主要介绍了mybatis example如何自动生成代码 排序语句,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • 关于Java单个TCP(Socket)连接发送多个文件的问题

    关于Java单个TCP(Socket)连接发送多个文件的问题

    这篇文章主要介绍了关于Java单个TCP(Socket)连接发送多个文件的问题,每次我只能使用一个 Socket 发送一个文件,没有办法做到连续发送文件,本文来解决这个问题,需要的朋友可以参考下
    2023-04-04
  • Java 网络编程总结

    Java 网络编程总结

    这篇文章主要给大家分享Java 网络编程的一个总结,说到网络编程肯定都会想到IP地址、端口、通信协议等一些必不可少的元素,下面来看看文章的详细介绍吧
    2021-11-11
  • JAVA使用ElasticSearch查询in和not in的实现方式

    JAVA使用ElasticSearch查询in和not in的实现方式

    今天小编就为大家分享一篇关于JAVA使用Elasticsearch查询in和not in的实现方式,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • SpringMVC中@ModelAttribute与@RequestBody的区别及说明

    SpringMVC中@ModelAttribute与@RequestBody的区别及说明

    这篇文章主要介绍了SpringMVC中@ModelAttribute与@RequestBody的区别及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • SpringJDBC源码初探之DataSource类详解

    SpringJDBC源码初探之DataSource类详解

    文章介绍了Java JDBC规范中的DataSource接口及其在Spring框架中的增强功能,包括连接池、事务管理等,重点分析了三种核心实现
    2025-08-08
  • SpringBoot整合Milvus的实现

    SpringBoot整合Milvus的实现

    本文主要介绍了SpringBoot整合Milvus的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • SpringBoot深入分析运行原理与功能实现

    SpringBoot深入分析运行原理与功能实现

    我们发现springBoot程序开发比spring程序编写起来容易的多。配置简洁,依赖关系简单,启动运行容易。那么结下了我们我们就要思考一下入门程序中的这些功能是怎么实现的
    2022-09-09

最新评论