java基础-ArrayList源码分析

1.ArrayList arraylist能够说是java开发者用过最多的集合了,应该没有之一吧?闲话少说,直接上代码java

private transient Object[] elementData;
private int size;

经过上面这行咱们认识到ArrayList的本质其实就是一个数组,而且提供了一个size属性来保存集合中元素的个数。数组

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

    public ArrayList() {
        this(10);
    }

这里贴出两个构造方法,很好理解,若是构造时传入int类型的参数一个,那么就建立一个initialCapacity大小的数组,若是使用无参构造函数,则默认初始化一个长度为10的数组函数

下面开始将有针对性的分析几个经常使用的方法,如add、remove、get等this

public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
    private void ensureCapacityInternal(int minCapacity) {
        modCount++;
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(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);
    }

这里给出了和add方法相关的全部函数,逻辑很简单,进入add方法后先判断容量,调用ensureCapacityInternal(size + 1)确保数组还有空闲空间可以再存放一个元素。 当元素个数即size+1大于数组长度,其实至关于元素个数等于数组长度,即数组已满,调用grow函数来扩展数组长度。 grow中的逻辑也很容易理解,(oldCapacity >> 1)至关于(oldCapacity / 2),即默认扩大到元长度的1.5倍,下面就是检查这个新长度是否符合逻辑,最后使用Arrays.copyOf来扩容code

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

        modCount++;
        E oldValue = elementData(index);

        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // Let gc do its work

        return oldValue;
    }

rangeCheck检查传入的参数,大于size会抛出异常。if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index,numMoved);若是删除的不是最后一个元素,将elementData数组index后面的元素向前移动一位,因为System.arraycopy调用的是本地方法,因此看不到源码ci

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

        return elementData(index);
    }

get方法的代码更简单,判断index在正确范围以后直接使用数组下标取值。在这里也体现出了ArrayList的优点,快速访问。这里就简单介绍ArrayList的基本操做,有兴趣的同窗能够自行阅读源码element

相关文章
相关标签/搜索