ArrayList LinkedList源码解析(3)

我们由上面test2()方法可知,一个List,调用list.toArray()返回的Object数组的真实类型不一定是Object数组([Ljava.lang.Object;),当我们调用 Object[] objArray = collection.toArray(), objArray并不一定能够存放Object对象,所以上面的源码中对这种情况进行了判断。

我们接着看ArrayList中的方法:

add(E),当我们添加数据的时候,会遇到的一个问题就是:当里面的数组满了,没有可用的容量的怎么办?

/**
*插入对象,首先将size+1,产生一个minCapacity的变量,调用ensureCapacity(minCapacity)方法保证数组在插入一个元素时有可用的��量,然后将元素e放到数组elementData的size位置,最后将size+1
*/
public boolean add(E e) {
    ensureCapacity(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}

/**
*必要时数组的扩容 (如果想调整ArrayList的容量增长策略,可以继承ArrayList,override ensureCapacity()方法即可),
首先将modCount+1,modeCount表示修改数组结构的次数(维护在父类AbstractList中),如果入参minCapacity大于目前数组elementData的容量,则将容量扩展到 (oldCapacity * 3)/2 + 1,
若此时容量仍然小于 minCapacity,则直接将minCapacity设置为最新的容量,
最后使用Arrays.copyof()方法将原来elementData中元素copy到新的数组中,并将新数组赋值给elementData.
*/
public void ensureCapacity(int minCapacity) {
    modCount++;
    int oldCapacity = elementData.length;
    if (minCapacity > oldCapacity) {
        Object oldData[] = elementData;
        int newCapacity = (oldCapacity * 3)/2 + 1;
            if (newCapacity < minCapacity)
        newCapacity = minCapacity;
            // minCapacity is usually close to size, so this is a win:
            elementData = Arrays.copyOf(elementData, newCapacity);
    }
}

/**
*在指定下标Index处插入元素element,首先判断下标index的参数是否有效(不能小于0,不能大于size),否则抛出IndexOutOfBoundsException异常,然后调用ensureCapacity(size+1)要确保数组中有足够的容量来插入数据,
*然后调用System.arraycopy()方法, 从index下标开始,将elementData数组元素copy到 从index+1开始的地方,copy的长度为size-index,这样index下标处的位置就空了出来,然后将元素element放到下标为index处的位置,最后将size++.
*我们看到使用这个方法相比add(E),多了一步数组元素的复制的代价。
*/
public void add(int index, E element) {
    if (index > size || index < 0)
        throw new IndexOutOfBoundsException(
        "Index: "+index+", Size: "+size);

ensureCapacity(size+1);  // Increments modCount!!
    System.arraycopy(elementData, index, elementData, index + 1,
            size - index);
    elementData[index] = element;
    size++;
}

/**
*将元素element设值到下标为index处,返回原来index处的旧值。
*/
public E set(int index, E element) {
    RangeCheck(index);
    //获取index下标的旧值
    E oldValue = (E) elementData[index];
    //设值新的元素element到index处
    elementData[index] = element;
    return oldValue;
}

//边界检查,index越界的话,抛出异常IndexOutOfBoundsException
private void RangeCheck(int index) {
    if (index >= size)
        throw new IndexOutOfBoundsException(
        "Index: "+index+", Size: "+size);
}

/**
*将指定集合c中的元素按照其迭代器返回的顺序追加到本集合中,只要将任何一个元素插入到集合中都会返回true
*/
public boolean addAll(Collection<? extends E> c) {
    Object[] a = c.toArray();
        int numNew = a.length;
    //确保(size+a.length)有足够的容量去插入新元素
    ensureCapacity(size + numNew);  // Increments modCount
    //将数组a的内容追加到elementData数组的最后
        System.arraycopy(a, 0, elementData, size, numNew);
        size += numNew;
    //只要插入的元素个数>0就返回true
    return numNew != 0;
}

我们再看删除的方法

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/a28bd8cda7fd42444934c8d7ef084553.html