每日读源码(2)

今天还是要继续看一下ArrayList,做人不能半途而废咧。

先来讲一讲ensureCapacity(int minCapacity)这个方法。

官方文档的解释是

    /**
     * Increases the capacity of this ArrayList instance, if
     * necessary, to ensure that it can hold at least the number of elements
     * specified by the minimum capacity argument.
     *
     * @param   minCapacity   the desired minimum capacity
     */

大意就是让你的ArrayList实例能够确保可以保存下最低的minCapacity这么多个元素。
简单来说,就是如果你当前list的capacity小于minCapacity,那么就会触发一次扩容,而扩容最低是oldCapacity的1.5倍,若minCapacity>1.5*oldCapacity,那么直接容量大小扩到minCapacity。

这个方法有一个好处,在将这个好处之前先说一说add方法
二话不说,直接上代码

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

每一次add一个元素的时候,会先判断当前数组大小+1是否会越界,如果越界则触发扩容。
聪明的人就可以想到,如果在频繁向链表插入元素的情景下,将会多次触发扩容,因为ArrayList的扩容是每次将容量扩展到原来的1.5倍+1,这样的话会导致整体性能降低,所以如果提前设置一个大概的容量值minCapacity,那么系统会一次性将实例的capacity扩到minCapacity,而不会导致频繁触发grow方法。

再来看看contains(Object o)这个方法吧

这个的代码很简单

//二话不说上代码
    public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }

通过函数名也可以看到是查找该Object在链表中的位置,若位置大于0则代表存在。

再讲一讲ArrayList中的两种remove方法吧

其实我也不知道原来还有两种remove方法的。一脸懵逼中....

//二话不说还是上代码
    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;
    }
    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;
    }

两种方式,其实是差不多的,一个是通过下标删除,会返回对应下标上存储的对象,另外一种方法是传入一个Object o,从下标0开始遍历整个链表,删除掉第一个o。

每天看一点源代码,幸福生活每一天。

你可能感兴趣的:(每日读源码(2))