美文网首页
ArrayList-源码分析

ArrayList-源码分析

作者: 空城EN | 来源:发表于2018-03-19 22:10 被阅读0次

一个菜鸟的源码之路

测试代码

1.new初始化

1.当new一个ArrayList对象时,去看下ArrayList的构造函数,发现它的代码是这样的:

    /**
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

elementDataDEFAULTCAPACITY_EMPTY_ELEMENTDATA都是Object数组:

transient Object[] elementData; // non-private to simplify nested class access

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

为啥在初始化时,要指向这个数组,是为了避免我们反复的创建无用数组,所有新new出来的ArrayList底层数组都指向缓存在方法区里的Object[]数组。

2.add添加元素

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

首先会执行ensureCapacityInternal()函数,看下这个函数




到这里我们发现执行了Array.copyof()函数,再看下这个函数的实现

发现会调用System.arraycopy这个native方法,主要功能就是进行数组的拷贝,到目前是初始化了一个长度为10的数组,然后就到了下一步

将数组的第一个元素赋值e,然后size加一,然后add就操作完成了。

3.size()求大小


这个size就是上一步的size,每添加一个元素都会加1,所以求大小只要把这个值返回就行

4.ArrayList扩容

上方说道,添加以一个元素的时候,会初始化一个长度为10的数组,那当长度超过10时,会进行什么操作呢?还是来看看add的源码


和上方一样,还是会进到ensureCapacityInternal()中,但传入的值会是11

这一步,会进入循环,将minCapacity的值赋11,然后执行将其作为参数传入ensureExplicitCapacity()

这一步没区别,来看下一步

这是重点,首先将oldCapacity + (oldCapacity >> 1)值赋给newCapacity。>>是位运算,>>多少位=除以2的多少次方。这个意思就是每次超出数组大小都会扩大原来的1/2。然后后面就和前面一样,就不详细阐述了。

相关文章

网友评论

      本文标题:ArrayList-源码分析

      本文链接:https://www.haomeiwen.com/subject/pgayqftx.html