ArrayList集合底层代码的理解

1、首先我们需要了解的是ArrayList底层是基于数组实现的:根据索引定位元素快,增删需要做元素的移位操作。

1、创建ArrayList

首先是创建一个空的数组来存储相应的元素对象,并创建一个空数组,默认数组的长度我们设置为10;

    //创建一个空的数组
    transient Object[] elementData;
    //数组中元素的个数
    private int size;
    //创建一个默认空数组
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    //创建一个空数组
    private static final Object[] EMPTY_ELEMENTDATA = {};
    //定义数组的初始容量
    private static final int DEFAULT_CAPACITY = 10;

当我们第一次创建ArrayList对象的时候会调用ArrayList中的无参构造器,这时我们数组的长度就会变成默认的十个长度

    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

第二种创建方式:

有参构造器的创建,这个方法中传输了一个int类型的参数,就是你自己想定义的集合长度。当我们赋值进去后需要先判断这个数是否是大于0当大于0的时候我们就创建一个新的数组并把新的数组长度传给我们一开始定义的elementData;

如果传入的值等于0我们就把一个空数组传给elementDate因为可能有一些人需要创建空集合

其他的情况我们都抛出异常不予执行

    public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }

2、ArrayList中的扩容方法

我们先了解这个确认最后参数的方法;

当我们想要增加一个数组的时候我们需要传入一个值来,但是在这其中我们需要去判断我们的集合是否可以存入这个值所有我们就要与创建的elementDate相比较

    private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }

首先传入一个需要扩容的值,我们将老的数组长度赋值给oldCapacity ,把后面oldCapacity + (oldCapacity >> 1)扩容的长度赋值给新的数组长度如果传进来的数组与我们扩容的长度还要长我们就把这个传进来数组的长度当作我们新数组的长度即可否则如果新的扩容长度大于想要的长度我们就把这个扩容后的数组长度穿回去继续接收元素。

    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);
    }

3、ArrayList中的增加方法

首先我们对数组进行判断看它是否可以存储一个新的元素就是前面说过的扩容方法的前奏。如果数组的长度不够我们将会进行扩容。扩容后我们就将数值穿进去并进行以这样的方式存储。

    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

4、ArrayList中的删除方法

首先我们需要对传进来的元素进行对比

首先是用if语句判断是否为空因为空数组也是可以删除的,随后我们使用for循环一直遍历找到与传入的元素相等的集合元素并利用fastRemove进行删除。这个方法就是把要删除的元素的后面的所有元素想前移动以为并把这个数组赋值为空最后进行减少数组长度。

    public boolean remove(Object o) {
        if (o == null) {
            for (int index = 0; index < size; index++)
                if (elementData[index] == null) {
                    fastRemove(index);
                    return true;
                }
        } else {
            for (int index = 0; index < size; index++)
                if (o.equals(elementData[index])) {
                    fastRemove(index);
                    return true;
                }
        }
        return false;

5、Array中的修改方法

修改方法中传入的值分别是索引值以及要修改的数据值

首先我们对索引进行判断是否符合集合的长度不符合就不进行修改

判断进入后我们对elementDate数组进行查询,查询找打后可以进行赋值到oldValue中,随后把elementDate在index上的元素值换成传入的参数中的元素。

    public E set(int index, E element) {
        rangeCheck(index);

        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }

6、ArrayList中的查找方法

此方法比较简单

只需要判断传入的索引值是否符合集合的长度,符合后我们就返回elementDate集合中index这个位置的元素 。

    public E get(int index) {
        rangeCheck(index);

        return elementData(index);
    }

总结

ArrayList其中的使用原理还是数组,是通过数组来进行一些的操作,学习好前面的Java基础是为能看懂底层代码打好基础。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值