简单模拟ArrayList的实现

本文深入探讨了ArrayList的底层实现原理,通过自定义ArrayList类,详细讲解了其实现List接口的方法,包括添加、删除、查找等操作,以及异常处理和数组扩容策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ArrayList的底层本质是一个能够动态操作数据的Object数组,它实现了List接口(其提供了相关的添加、删除、修改、遍历等功能)。

  1. 模拟建立List接口
package com.data;

/**
 * 线性表接口
 */
public interface List {
    //返回线性表的大小,即数据元素个数
    public int size();

    //返回线性表中序号为index的元素
    public Object get(int index);

    //如果线性表为空返回true,否则返回false
    public boolean isEmpty();

    //判断线性表是否包含 指定元素
    public boolean contains(Object e);

    //返回数据元素e在线性表中的序号
    public int indexOf(Object e);

    //将数据元素e插到线性表中的index位置
    public void add(int index,Object e);

    //将数据元素e插到线性表中的末尾
    public void add(Object e);

    //将数据元素e插到元素obj之前
    public boolean addBefore(Object obj,Object e);

    //将数据元素e插到元素obj之后
    public boolean addAfter(Object obj,Object e);

    //删除线性表中序号为index的元素,并返回之
    public Object remove(int index);

    //删除线性表中第一个与e相同的元素
    public Object remove(Object e);

    //用元素e替换线性表中序号为index的元素,并返回原元素
    public Object replace(int index,Object e);
}
  1. 自定义异常类
package com.data.exception;

/**
 * 自定义异常类
 */
public class ArrayIndexOutOfBoundsException extends RuntimeException{
    public ArrayIndexOutOfBoundsException(){
        super();
    }
    public ArrayIndexOutOfBoundsException(String message){
        super(message);
    }
}
  1. 新建ArrayList类并实现List接口
package com.data.genericset;

import com.data.List;
import com.data.exception.ArrayIndexOutOfBoundsException;

import java.util.Arrays;

/**
 * 顺序表(底层采用的是数组,但长度可以动态的变化)
 */
public class ArrayList implements List {
    private Object[] elementData;//底层是一个未定义长度的数据
    private int size;//元素的个数

    public ArrayList(){
        //没有指定数组初始长度,设置默认长度为0
        //this.elementData = new Object[]{};
        this(4);
    }

    /**
     * 构造方法初始化数组
     * @param initialCapacity 数据的初始指定长度
     */
    public ArrayList(int initialCapacity){
        //为数据分配指定的数量空间
        this.elementData = new Object[initialCapacity];
        //指定顺序表的元素个数,默认是0
        size = 0;
    }

    @Override
    public int size() {
        return this.size;
    }

    @Override
    public Object get(int index) {
        if(index<0||index>=size){
            throw new ArrayIndexOutOfBoundsException("数组索引越界异常:"+index);
        }
        return this.elementData[index];
    }

    @Override
    public boolean isEmpty() {
        return this.size==0;
    }

    @Override
    public boolean contains(Object e) {
        if(this.indexOf(e)!=-1){
            return true;
        }
        return false;
    }

    @Override
    public int indexOf(Object e) {
        if(e==null){
            return -1;
        }
        for(int x=0;x<this.size;x++){
            if(this.elementData[x].equals(e)){
                return x;
            }
        }
        return -1;
    }

    @Override
    public void add(int index, Object e) {
        //判断index的位置是否正确
        if(index<0||index>this.size){
            throw new ArrayIndexOutOfBoundsException("数组索引越界异常:"+index);
        }
        //如果数组满了,就扩容
        if(this.size==this.elementData.length){
            this.grow();
        }
        //后移index及其后面的元素元素,从最后一个元素开始
        for(int x=this.size;x>index;x--){
            this.elementData[x] = this.elementData[x-1];
        }
        //为数据赋值,线性表中的元素个数加1
        this.elementData[index]=e;
        this.size++;
    }

    @Override
    public void add(Object e) {
        this.add(this.size,e);
    }

    @Override
    public boolean addBefore(Object obj, Object e) {
        int index = this.indexOf(obj);
        if(index==-1){//查询不到数据
            return false;
        }else{
            this.add(index,e);
        }
        return true;
    }

    @Override
    public boolean addAfter(Object obj, Object e) {
        int index = this.indexOf(obj);
        if(index==-1){//查询不到数据
            return false;
        }else{
            this.add(index+1,e);
        }
        return true;
    }

    @Override
    public Object remove(int index) {
        Object obj = null;
        if(index<0||index>=this.size){//判断是否存在数据
            ;
        }else{
            obj = this.elementData[index];
            for(int x=index;x<this.size-1;x++){
                this.elementData[x] = this.elementData[x+1];
            }
            this.size--;
        }
        return obj;
    }

    @Override
    public Object remove(Object e) {
        return this.remove(this.indexOf(e));
    }

    @Override
    public Object replace(int index, Object e) {
        if(index<0||index>=this.size){//判断是否存在数据
            return null;
        }
        Object obj = this.elementData[index];
        this.elementData[index] = e;
        return obj;
    }

    private void grow(){
        //复制创建新的数组,数组长度增长50%;
        this.elementData = Arrays.copyOf(this.elementData,
                this.elementData.length+(this.elementData.length>>1));
    }

    @Override
    public String toString() {
        if(this.size==0){
            return "[]";
        }
        /**
            String只能存放不可变的字符串,而StringBuffer和StringBuilder存放可变的字符串
            String与StringBuilder是线程非安全的(速度较快),而StringBuffer是线程安全的(速度较慢)
            考虑到此处为单线程操作,因此使用StringBuilder
        */
        StringBuilder builder = new StringBuilder("[");
        for(int x=0;x<this.size;x++){
            builder.append(this.elementData[x]).append(",");
        }
        builder.delete(builder.length()-1,builder.length()).append("]");
        return builder.toString();
    }
}
  1. 编写测试代码
import com.data.List;
import com.data.genericset.ArrayList;

public class ArrayListTest {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add(123);
        list.add(456);
        list.add(789);
        list.add(555);
        list.add(0,"haha");
        System.out.println("数组长度:"+list.size());
        System.out.println("是否为空:"+list.isEmpty());
        System.out.println("是否包含haha:"+list.contains("haha"));
        System.out.println("haha位置:"+list.indexOf("haha"));
        System.out.println("输出集合:"+list);
        System.out.println("在haha之前插入hello:"+list.addBefore("haha","hello"));
        System.out.println("输出集合:"+list);
        System.out.println("在haha之后插后world:"+list.addAfter("haha","world"));
        System.out.println("输出集合:"+list);
        System.out.println("删除第5个元素:"+list.remove(5));
        System.out.println("输出集合:"+list);
        System.out.println("删除haha:"+list.remove("haha"));
        System.out.println("输出集合:"+list);
        System.out.println("将最后一个元素换成haha:"+list.replace(list.size()-1,"haha"));
        System.out.println("输出集合:"+list);
    }
}
  1. 运行程序查看控制台输出,发现所有操作都能正常完成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值