跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava算法

Java ArrayList 底层方法自我实现

Java ArrayList 基于动态数组实现 List 接口,通过手写代码演示其核心方法。涵盖初始化、扩容机制(grow)、元素增删改查(add, remove, get, set)及遍历查找(contains, indexOf)。重点解析数组满时如何复制扩容、插入删除时的数据移动逻辑,帮助深入理解顺序表底层原理。

1951018925发布于 2026/3/28更新于 2026/10/2590 浏览
Java ArrayList 底层方法自我实现

在这里插入图片描述

🎁个人主页:User_芊芊君子
🎉欢迎大家点赞👍评论📝收藏⭐文章
🔍系列专栏:Java.数据结构

在这里插入图片描述

在这里插入图片描述

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

一、定义 ArrayList 类

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

public class MyArrayList implements IList {
    private int[] arr; // 存储数据
    private int usedSize; // 有效数据个数
    public static     ; 

      {
        .arr =  [DEFAULT_CAPACITY];
    }
}
final
int
DEFAULT_CAPACITY
=
10
// 默认数组容量
public
MyArrayList
()
this
new
int

二、常见方法实现

ArrayList 的常见方法如下:

在这里插入图片描述

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

public void add(int data) {
    // 判断顺序表是否满了
    if (isFull()) {
        // 扩容 grow();
        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 checkPos(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,让我们认识到了,数据结构的学习和使用,要考虑到所有方面,对我们的逻辑思维能力要求很高,同样也会提高我们这方面的能力,相关的其他内容后面会详细道来

目录

  1. 一、定义 ArrayList 类
  2. 二、常见方法实现
  3. 1. add(int data):新增元素,添加在数组后面
  4. 2. add(int pos, int data): 再 pos 位置添加元素
  5. 3. contains(int toFind):判断是否包含某个元素
  6. 4. indexOf(int toFind): 查找某个元素对应的位置
  7. 5. get(int pos): 获取 pos 位置的元素
  8. 6. set(int pos, int value):给 pos 位置的元素设为 value
  9. 7. remove(int toRemove):删除第一次出现的关键字 key
  10. 8. size():获取顺序表长度
  11. 9. clear():清空顺序表
  12. 三、总结

更多推荐文章

查看全部
  • llama.cpp 多 GPU 分布式计算优化实践
  • CTF 逆向:RC4、TEA 与 Base64 加密算法特征识别与魔改分析
  • 生信零基础到独立项目:3 个月模块化学习计划
  • MiniMax 海螺 AI:图片与文本生成高质量视频指南
  • Python 字符串格式化:% 运算符详解
  • 《Agent Runtime 工程化》第一章 Agent Runtime 全景:导读
  • LazyLLM 多 Agent 应用实战:源码部署与可视化调试指南
  • 数据结构:双向链表详解与实现
  • GLM-4.5-Air-Base 开源:1060 亿参数智能推理模型免费商用
  • 进阶数据结构:AVL 树
  • llama.cpp 多 GPU 分布式计算优化指南
  • 基于 Java SpringBoot 的企业设备信息一体化管理系统
  • Spring Boot 整合 WebService 客户端:基于 WSDL 自动生成代码
  • DeepSeek-R1-Distill-Llama-8B 本地部署与 Docker Compose 服务化
  • 前端 Base64 格式文件上传详解:原理、实现与最佳实践
  • Mac Mini 部署 OpenClaw 实战指南
  • 利用 AI 快速构建 7c 原则视频生成工具
  • Linux 环境下 OpenClaw 安装、初始化与 Web UI 配置指南
  • Hunyuan-MT-7B WebUI 部署后无法访问网页的排查指南
  • 从一句话到一张图:看懂 Stable Diffusion 的潜空间扩散生成流程

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online