自我实现ArrayList

15 篇文章 0 订阅
面试者经常遇到集合类源码的问题。我们不求将所有的细节都记住,但ArrayList与LinkedList比较、add、get、remove、扩容、及相关时间复杂度等核心思想要理解得一清二楚。

ArrayList底层用数组实现,可以快速访问某一节点的值,但插入删除会调用System.arraycopy方法,数组容量不够时需进行扩容,扩容采用新的大数组取代旧的数组。

public class MyArrayList<E> {

    private Object[] elementData; //采用数组存储

    public int size;// 数组中元素长度

    private static final int INITIAL_CAPACITY = 10;// 初始容量


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


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


    private void ensureCapacity(int minCapacity) {
        int oldCapacity = elementData.length;
        if (minCapacity > oldCapacity) {
            int newCapacity = (oldCapacity * 3) / 2 + 1;
            if (newCapacity < minCapacity)
                newCapacity = minCapacity;

            elementData = Arrays.copyOf(elementData, newCapacity);// 扩容调用Arrays.copyOf方法 将容量扩为原数组长度的3/2, 现有的数组引用指向了新的数组
        }
    }

    // 在數組末尾添加元素 時間複雜度O(1)
    public void add(E e) {
        if (e == null)
            return;
        ensureCapacity(size + 1);
        elementData[size++] = e;
    }


    public void add(E e, int index) {
        if (e == null || index > size || index < 0)
            return;
        ensureCapacity(size + 1);

        System.arraycopy(elementData, index, elementData, index + 1, size - index);  // 数组中间添加元素 
        elementData[index] = e;
        size++;
    }


    public E get(int index) {
        if (index > size || index < 0)
            return null;
        return (E) elementData[index]; // 按位置获取元素 时间复杂度为O(1)
    }


    public E remove(int index) {
        if (index > size || index < 0)
            return null;
        E oldValue = get(index);
        int numMoved = size - index - 1;
        if (numMoved > 0) // 删除元素 平均复杂度为O(n)
            System.arraycopy(elementData, index + 1, elementData, index, numMoved);
        elementData[--size] = null;
        return oldValue;
    }
}


可见,ArrayList可以根据索引快速访问任意元素,但插入、删除、扩容操作会调用System.arrayCopy()方法,这是个非常占用系统资源的操作。当你遇到访问元素比插入或者是删除元素更加频繁的时候,你应该使用ArrayList,在频繁的插入或者是删除元素的情况下,LinkedList的性能会更加好一些。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值