java集合源码阅读(一) ArrayList

2019-03-21  本文已影响0人  坠叶飘香

1. ArrayList的继承关系

ArrayList.png

2.重要属性

(1)size:实际元素个数
因为size这个值是时时更新的,通过size() 获取元素个数时,不耗时。
private int size;
public int size() {
    return size;
}
(2)elementData:数据容器
从这里可以看出,ArrayList的数据实际上是存放在一个数组中,所以ArrayList可以快速的获取处于index位的元素
transient Object[] elementData;
public E get(int index) {
    rangeCheck(index);
    return elementData(index);
}

3.add方法

数组elementData容器的默认大小0,第一次add数据时,会创建一个length为10的elementData;以后的每次add动作一旦发现elementData的length不够放入新的元素,会再次创建一个新的elementData,
新elementData的length=oldlength +oldlength/2
public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}

4.remove方法

(1) 通过index删除相应位置的元素:直接执行System.arraycopy
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);
    }
    //这里不忘把最后一个元素设置为null,让GC可以将它回收
    elementData[--size] = null; // clear to let GC do its work
    return oldValue;
}
(2) 通过value移除
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;
}

5.set方法:直接修改数组位于index处的元素

public E set(int index, E element) {
    rangeCheck(index);

    E oldValue = elementData(index);
    elementData[index] = element;
    return oldValue;
}

6.关于使用ListIterator还是for遍历的问题

两种遍历的不同点主要在获取index处的元素

从代码上看ListIterator比for多了两次i的检测和一次cursor的求值;在数据量很小的情况下没有什么差别,
用5000个数据来遍历的话,for的时间为1,ListIterator为2。

ListIterator:
@SuppressWarnings("unchecked")
public E next() {
    checkForComodification();
    int i = cursor;
    if (i >= size)
        throw new NoSuchElementException();
    Object[] elementData = ArrayList.this.elementData;
    if (i >= elementData.length)
        throw new ConcurrentModificationException();
    cursor = i + 1;
    return (E) elementData[lastRet = i];
}
for:
public E get(int index) {
    rangeCheck(index);
    return elementData(index);
}
上一篇下一篇

猜你喜欢

热点阅读