简单纯手写ArrayList集合

首先分析ArrayList底层实现原理

新增操作:源码中ArrayList构造方法,先定义一个空数组,当我们执行add方法的时候,再对数组进行扩容,第一次扩容后数组长度为10,也就是ArrayList以懒加载的形式初始化容量(起始容量为0),执行add方法的时候才会将容量从0扩为10

    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
    private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }

扩容的源码

    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

删除操作:删除index下标位置的元素,后面的元素整体往前移动一位,最后的位 置为null

源码如下

    private void fastRemove(int index) {
        modCount++;
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work
    }

分析完原理后,我们手写ArrayList

import java.util.Arrays;

public class MyArrayList<E> {

    定义Object类型的数组
    private Object[] elementData;
    //统计变量,用于统计数组元素的真实个数
    private int size;

    public MyArrayList() {
        elementData = new Object[10];
    }

    public void add(E e) {
        if (size >= elementData.length) {
            //数组扩容,容量默认增加10
            int newCapacity = elementData.length + 10;
            elementData = Arrays.copyOf(elementData, newCapacity);
        }
        elementData[size++] = e;
    }

    public Object get(int index) {
        if (index < 0 || index > size) {
            throw new ArrayIndexOutOfBoundsException();
        }
        return elementData[index];
    }

    //删除指定索引处的元素
    public void deleteElementByIndex(int index) {
        if (index < 0 || index > size) {
            throw new ArrayIndexOutOfBoundsException();
        }
        System.arraycopy(elementData, index + 1, elementData, index, size - index - 1);
        elementData[--size] = null;
    }

    //为了方便看效果,我们覆写toString()方法
    @Override
    public String toString() {
        //构建一个新的数组,长度为size
        Object[] newdata = new Object[size];
        //将data中的元素拷贝到新数组中
        System.arraycopy(elementData, 0, newdata, 0, size);
        //利用Arrays类,将数组转换成字符串
        return Arrays.toString(newdata);
    }
    
}

ArrayList查询的时间复杂度

O(1):基于数组的下标index查询,只需要查询一次arrayList[index]

O(n):根据元素查询,将整个数组遍历,从头遍历到尾部

关于ArrayList总结如下:

增:初始化容量为10的数组,如果底层数组容量不够的情况下 就会触发动态扩容机制,效率非常低

删:删除index下标位置的元素,后面的元素整体往前移动一位,最后的位 置为null,效率也是非常低

改:如果是根据index下标修改,效率是非常高--时间复杂度o(1);如果根据元素值 修改效率非常低

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值