源码01_手写ArrayList

该博客展示了如何从头实现一个MyArrayList类,该类实现了MyList接口,包括添加、删除、获取和修改元素等基本操作。博客通过示例代码详细解释了每个方法的实现逻辑,如扩容策略和数组元素的移动。此外,还提供了测试用例来验证自定义ArrayList的功能。
摘要由CSDN通过智能技术生成

定义MyList<E>接口

/**
 * List接口
 *
 * @author gaorimao
 * @date 2021/07/20
 */
interface MyList<E> {
    /**
     * 添加元素
     *
     * @param object 对象
     */
    void add(E object);

    /**
     * 在指定索引处添加元素
     *
     * @param object 对象
     */
    void add(int index, E object);

    /**
     * 移除元素
     *
     * @param object 对象
     */
    boolean remove(E object);

    /**
     * 移除index索引处的元素
     *
     * @param index 对象
     */
    Object remove(int index);

    /**
     * 获取ArrayList的元素个数
     */
    int size();

    /**
     * 获取index处的元素
     */
    Object get(int index);

    /**
     * 把index处的元素修改为obj
     *
     * @param index
     * @param obj
     */
    void set(int index, E obj);
}

定义MyArrayList<E>类实现MyList<E>接口

import java.util.Arrays;

/**
 * 自己实现Arraylist
 *
 * @author gaorimao
 * @date 2021/07/20
 */
public class MyArrayList<E> implements MyList<E> {
    /**
     * elementData
     */
    private transient Object[] elementData;

    /**
     * ArrayList实际数量
     */
    private int size;

    /**
     * 构造方法
     */
    public MyArrayList() {
        //不设置集合长度默认长度10
        this(10);
    }

    /**
     * 构造方法,初始化集合长度
     *
     * @param initialCapacity 初始容量
     */
    public MyArrayList(int initialCapacity) {
        if (initialCapacity < 0){
            throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);
        }
        elementData = new Object[initialCapacity];
    }

    /**
     * 扩容
     *
     * @param minCapacity 最小容量
     */
    private void ensureExplicitCapacity(int minCapacity) {
        //如果元素个数和容量相等,则需要扩容
        if (size == minCapacity) {
            int oldCapacity = elementData.length;
            // << : 左移运算符,num << 1, 相当于num乘以2
            // >> : 右移运算符,num >> 1, 相当于num除以2
            //基于1.5倍扩容
            int newCapacity = oldCapacity + (oldCapacity >> 1);
            //如果扩容后的容量<扩容之前的容量,则把扩容前的容量赋值给扩容后的容量
            if (newCapacity < minCapacity) {
                newCapacity = minCapacity;
            }
            //根据扩容后的容量复制一个新数组
            elementData = Arrays.copyOf(elementData, newCapacity);
        }
    }

    /**
     * 检测数组是否下标越界,是抛出越界异常
     *
     * @param index
     */
    private void rangeCheck(int index) {
        if (index >= size || index < 0) {
            throw new IndexOutOfBoundsException("length--->" + index);
        }
    }

    @Override
    public void add(E object) {
        ensureExplicitCapacity(size + 1);
        elementData[size] = object;
        size++;
    }

    /**
     * 指定索引添加数据
     * 指定索引处到最后数据全部后移一位
     * 在指定索引处插入新数据
     *
     * @param index  指数
     * @param object 对象
     */
    @Override
    public void add(int index, E object) {
        rangeCheck(index);
        //判断集合长度,长度不够扩容
        ensureExplicitCapacity(size + 1);
        //计算添加索引处到最后一位数的长度
        int numMoved = size - index;
        //拷贝指定索引数据后移
        System.arraycopy(elementData, index, elementData, index + 1, numMoved);
        //指定索引插入
        elementData[index] = object;
        size++;
    }

    @Override
    public boolean remove(E object) {
        for (int i = 0; i < elementData.length; i++) {
            Object element = elementData[i];
            if (element.equals(object)) {
                remove(i);
                return true;
            }
        }
        return false;
    }

    @Override
    public Object remove(int index) {
        //获取对象
        Object object = get(index);
        //计算删除索引处到最后一位数的长度
        int numMoved = size - index - 1;
        //如果删除的最后一位或只有一位,不对数组做任何操作
        if (numMoved > 0) {
            System.arraycopy(elementData, index + 1, elementData, index, numMoved);
        }
        //删除数组最后一位的数据
        elementData[--size] = null;
        return object;
    }

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

    @Override
    public Object get(int index) {
        rangeCheck(index);
        return elementData[index];
    }

    @Override
    public void set(int index, E obj) {
        rangeCheck(index);
        elementData[index] = obj;
    }
}

测试

public class Test {
    public static void main(String[] args) {
        MyArrayList<String> list = new MyArrayList<String>();
        list.add("张三");
        System.out.println("--------新增张三------------");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
        list.add("李四");
        System.out.println("--------新增李四------------");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }

        list.add(1, "555");
        System.out.println("--------指定索引1添加555------------");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
        list.add(1, "666");
        System.out.println("--------指定索引1添加666------------");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }

        list.remove(1);
        System.out.println("--------指定删除索引1元素后--------");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
        list.remove("555");
        System.out.println("--------指定对象555删除后--------");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }

        list.set(1, "王五");
        System.out.println("--------修改1索引元素为王五后------------");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值