Java集合类源代码分析二:ArrayList(2)

时间:2022-01-29 17:01:05

继续上一篇博客介绍,

 

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


Get方法其实就是从Object数组中取数据。

 

public E set(int index, E element) {
        RangeCheck(index);
 
        E oldValue = (E) elementData[index];
        elementData[index] = element;
        return oldValue;
}
 

Set方法有两个参数,第一个是索引,第二个是具体的值,作用就是将索引下的值变成传入参数的值。所以get方法实现是先将当前数组索引值的数据赋值到一个变量,此变量作为返回值传出,之后将当前的索引的值改成传入的值。


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

Add方法是在数组后面添加一个元素,首先调用ensureCapacity方法,


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


这个方法首先将当前未添加的数组长度拿到,之后判断minCapacity(即size+1)是否大于oldCapacity,若大于,则调整容量为max((oldCapacity*3)/2+1,minCapacity),调整elementData容量为新的容量,即将返回一个内容为原数组元素,大小为新容量的数组赋给elementData;否则不做操作。

容量的拓展将导致数组元素的复制,多次拓展容量将执行多次整个数组内容的复制。若提前能大致判断list的长度,调用ensureCapacity调整容量,将有效的提高运行速度

后面的add(intindex, E element)和addAll(Collection<?extends E> c)以及addAll(int index,Collection<? extends E> c)都是和上面add方法实现思路类似。

 

下面看一下remove方法:


public E remove(int index) {
    RangeCheck(index);
 
    modCount++;
    E oldValue = (E) elementData[index];
 
    int numMoved = size - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                 numMoved);
    elementData[--size] = null; // Let gc doits work
 
    return oldValue;
}
 

这个方法主要是elementData[--size] = null这句话是可以让垃圾回收机制来收集。

 

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

这个方法调用了fastRemove方法,这个方法实现的思路和remove(index)方法实现的思路是一致的。

 

后面还有一些其他的方法,在这里不再赘述,到这里对ArrayList源代码就介绍完成了,知道这些源码之后要知道它的数据结构其实是数组,而且通过调整数组长度来避免数组带来的不能扩展的弊端,但是这样一来带来的性能是需要考虑的,所以如果在初始化的时候进行能够传入大小就传入大小,如果不清楚大小长度那么就可能会出现性能下降的问题,所以这一点是需要注意的。