模拟实现顺序表 —— ArrayList

ArrayLiist的使用

java 复制代码
import java.util.ArrayList;
import java.util.List;

// 顺序表的使用
public class Demo {
    public static void main(String[] args) {
        // 初始化顺序表
        List<Integer> list = new ArrayList<>();

        // 添加数据
        list.add(1);
        list.add(1);
        list.add(1);
        list.add(1,2);
        list.add(3);
        list.add(4);
        list.add(4);
        list.add(5);
        list.add(6);
        System.out.println(list);

        // 删除数据
        list.remove(1);
        list.remove(new Integer(1));
        System.out.println(list);

        // 更新数据
        list.set(0, 111);
        System.out.println(list);

        // 获取元素在顺序表中第一次出现的位置
        System.out.println(list.indexOf(4));
        System.out.println(list.indexOf(1));

        // 获取元素在顺序表中最后一次出现的位置
        System.out.println(list.lastIndexOf(4));
        System.out.println(list.lastIndexOf(5));

        // 获取顺序表的长度
        System.out.println(list.size());

        // 判断顺序表是否为空
        System.out.println(list.isEmpty());

        // 判断某个元素是否在顺序表中存在
        System.out.println(list.contains(111));
        System.out.println(list.contains(112));

        // 获取给定下标的元素值
        System.out.println(list.get(1));
        System.out.println(list.get(3));
    }
}

以下代码是针对上述 ArrayList 类的模拟实现

MyArrayList

java 复制代码
import java.util.Arrays;

// 模拟实现顺序表
public class MyArrayList {
    // 底层数组默认大小
    private static final int DEFAULT_CAPACITY = 10;
    private int[] elem;
    // 累计数组中的元素个数
    private int usedSize;

    // 构造器
    public MyArrayList() {
        this(DEFAULT_CAPACITY);
    }

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

    // 添加数据
    public void add(int data) {
        // 判满
        if (usedSize == elem.length) {
            this.elem = Arrays.copyOf(this.elem, this.elem.length * 2);
        }
        // 添加元素到数组后面
        this.elem[usedSize++] = data;
    }

    // 根据下标添加数据
    public void add(int index, int data) {
        // 判断下标是否越界
        if (index < 0 || index > usedSize) {
            throw new IndexOfArrayException("下标异常: " + index);
        }

        // 判满
        if (usedSize == elem.length) {
            this.elem = Arrays.copyOf(this.elem, this.elem.length * 2);
        }

        // 把 index 处及其后面的下标往后移
        for (int i = usedSize; i > index; i--) {
            this.elem[i] = this.elem[i-1];
        }
        // 把要插入的元素放到 index 处
        this.elem[index] = data;
        usedSize++;
    }

    // 删除数据
    public void removeOfElement(int data) {
        // 获取待删除元素的下标
        int index = -1;
        for(int i = 0; i < usedSize; i++) {
            // 找到了要删除元素
            if(elem[i] == data) {
                // 获取下标
                index = i;
                break;
            }
        }
        // 没有找到
        if (index == -1) return;
        // 找到了进行删除操作
        removeOfIndex(index);
    }

    // 根据下标删除数据
    public void removeOfIndex(int index) {
        // 判断下标是否越界
        if (index < 0 || index >= usedSize) {
            throw new IndexOfArrayException("下标异常: " + index);
        }

        // 把要删除下标的后面元素前移
        for (int i = index; i < usedSize - 1; i++) {
            this.elem[i] = this.elem[i+1];
        }
        // 数组中有效长度 -1
        usedSize--;
    }

    // 删除顺序表中所有与给定数据相同的值
    public void remove(int data) {
        // 临时数组
        int[] tmp = new int[elem.length];
        int index = 0;

        // 将不同的元素放到tmp数组中
        for(int i = 0; i < usedSize; i++) {
            if (elem[i] != data) {
                tmp[index++] = elem[i];
            }
        }
        // 将删除重复元素后的数组重新赋给 elem 数组
        this.elem = tmp;
        // 重置有效元素个数
        usedSize = index;
    }

    // 获取给定值在顺序表中第一次出现的位置
    public int indexOf(int data) {
        for(int i = 0; i < usedSize; i++) {
            // 找到了
            if (elem[i] == data) {
                return i;
            }
        }
        // 没找到
        return -1;
    }

    // 获取给定值在顺序表中最后一次出现的位置
    public int lastIndexOf(int data) {
        for (int i = usedSize - 1; i >= 0; i--) {
            // 找到了
            if (elem[i] == data) {
                return i;
            }
        }
        return -1;
    }

    // 判断给定值是否在顺序表中存在
    public boolean contains(int data) {
        for (int i = 0; i < usedSize; i++) {
            // 存在
            if (elem[i] == data) {
                return true;
            }
        }
        return false;
    }

    // 获取下标处的元素
    public int get(int index) {
        if (index < 0 || index >= usedSize) {
            throw new IndexOfArrayException("下标异常: " + index);
        }
        return elem[index];
    }

    // 更新下标的元素
    public void set(int index, int data) {
        if (index < 0 || index >= usedSize) {
            throw new IndexOfArrayException("下标异常: " + index);
        }
        elem[index] = data;
    }

    // 判断顺序表是否为空
    public boolean isEmpty() {
        return usedSize == 0;
    }

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

    // 打印顺序表的值
    public void display() {
        for (int i = 0; i < usedSize; i++) {
            System.out.print(elem[i] + " ");
        }
        System.out.println();
    }

    // 清空顺序表
    public void clear() {
        this.elem = null;
        usedSize = 0;
    }
}

Exception

java 复制代码
public class IndexOfArrayException extends RuntimeException{
    public IndexOfArrayException() {
    }

    public IndexOfArrayException(String message) {
        super(message);
    }
}

Test

java 复制代码
public class MyArrayListTest {
    public static void main(String[] args) {
        MyArrayList list = new MyArrayList();
        list.add(1);
        list.add(2);
        list.add(3);
        list.display();

        list.add(0, 111);
        list.add(3, 112);
        list.add(2, 114);
        list.display();

        list.removeOfElement(1);
        list.removeOfElement(111);
        list.removeOfElement(3);
        list.display();

        list.removeOfIndex(0);
        list.removeOfIndex(1);
        list.display();
        list.removeOfIndex(0);
        list.display();

        list.add(1);
        list.add(2);
        list.add(1);
        list.add(1);
        list.add(0);
        list.add(1);
        list.add(1);
        list.add(3);
        list.display();
        list.remove(1);
        list.display();

        list.add(2);
        list.add(0);
        list.add(2);
        list.display();
        System.out.println(list.indexOf(2));
        System.out.println(list.lastIndexOf(0));

        System.out.println(list.contains(9));
        System.out.println(list.contains(2));

        System.out.println(list.isEmpty());

        System.out.println(list.size());

        System.out.println(list.get(0));
        list.set(0, 111);
        list.display();
    }
}

通过模拟实现ArrayList后,会对底层的原理以及思想会更加理解。

相关推荐
jinanwuhuaguo2 分钟前
(第三十三篇)五月的文明奠基:OpenClaw 2026.5.2版本的文明级解读
android·java·开发语言·人工智能·github·拓扑学·openclaw
笨笨饿8 分钟前
69_如何给自己手搓一个串口
linux·c语言·网络·单片机·嵌入式硬件·算法·个人开发
xmjd msup36 分钟前
spring security 超详细使用教程(接入springboot、前后端分离)
java·spring boot·spring
纽扣6671 小时前
【算法进阶之路】链表进阶:删除、合并、回文与排序全解析
数据结构·算法·链表
952361 小时前
SpringBoot统一功能处理
java·spring boot·后端
Lyyaoo.1 小时前
优惠券秒杀业务分析
java·开发语言
消失的旧时光-19431 小时前
统一并发模型:线程、Reactor、协程本质是一件事(从线程到协程 · 第6篇·终章)
java·python·算法
勿忘初心12211 小时前
Java 国密 SM4 加密工具类实战(Hutool + BouncyCastle)|企业级数据加密 + 兼容 JDK8
java·数据安全·数据加密·后端开发·企业级开发·国密 sm4
庞轩px1 小时前
第8篇:原子类与CAS底层原理——无锁并发的实现
java·cas·乐观锁·aba·无锁编程·自旋
智者知已应修善业1 小时前
【51单片机不用数组动态数码管显示字符和LED流水灯】2023-10-3
c++·经验分享·笔记·算法·51单片机