集合框架系列(二)ArrayList源码分析-Java8

一、ArrayList简介

ArrayList的底层是一个数组,刚开始有一定的大小,随着加入的元素增多后,底层数组会扩容。

二、ArrayList构造方法

1、ArrayList()

底层初始化一个空的对象数组。

2、ArrayList(int initialCapacity)

底层初始化一个对象数组,数组的长度为initialCapacity,数组最后一项为elementData[initialCapacity-1]。

3、ArrayList(Collection<? extends E> c)

将实现Collection接口的集合转换为对象数组,赋值给ArrayList的底层数组。

三、ArrayList.add(E)插入元素

第一步:判断对象数组空间是否已满,如果已满或数组长度为0,则进行扩容;如果空间未满,则直接跳到第二步;

            扩容:当数组长度为0时,数组长度初始化为DEFAULT_CAPACITY=10(在Java8中,DEFAULT_CAPACITY变量只用到了这一次);接下来的扩容,数组长度增加原大小右移1位(oldCapacity >> 1),即扩容后数组长度=扩容前数组长度+扩容前数组长度二进制右移一位。最终通过Arrays.copyOf()进行扩容。

第二步:将加入的对象放入数组第一个非空位置。

四、ArrayList.get(int)查找元素

第一步:检查入参数值是否小于集合中元素的个数,如果不是,则报出IndexOutOfBoundsException;

    private void rangeCheck(int index) {
        if (index >= size)//这个size是集合中元素的个数
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

第二步:返回对象数组中,如参数值对应位置的对象

    E elementData(int index) {
        return (E) elementData[index];
    }

五、ArrayList.remove()移除元素

1、通过下标移除元素:ArrayList.remove(int)

    public E remove(int index) {
        rangeCheck(index);//第一步:检查入参数值是否小于集合中元素的个数,如果不是,则报出IndexOutOfBoundsException

        modCount++;
        E oldValue = elementData(index);//第二步:找出入参下标对应的对象

        //第三步:将入参下标后面的元素全部向前移动一位(通过System.arraycopy()实现)
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index, numMoved);
        elementData[--size] = null;//第四步:记录集合元素个数的变量减一,原数组中最后一个非空位置置为空

        return oldValue;
    }

2、通过对象移除元素:ArrayList.remove(java.lang.Object)

第一步:通过入参对象找到元素所在位置的下标(用for循环查找);

第二步:通过下标将元素移除,与ArrayList.remove(int)不同的是,这里没有检查下标是否越界(因为没有必要)。

六、ArrayList总结

  • ArrayList的底层是一个数组,这个数组可以扩容;
  • ArrayList的所有方法都是线程不安全的,使用需要考虑是否合适。

猜你喜欢

转载自my.oschina.net/u/2896303/blog/1799160