源码阅读—List分支-ArrayList

基本数据结构是数组。


实现了List接口,允许元素为空。
extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable


属性有:
private static final long serialVersionUID = 8683452581122892189L;
//默认承载力
private static final int DEFAULT_CAPACITY = 10;
//空数组
private static final Object[] EMPTY_ELEMENTDATA = {};
//元素数组
private transient Object[] elementData;
//元素个数
private int size;
//默认最大个数
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;


和Vector类似,但是ArrayList是非线程安全
List list = Collections.synchronizedList(new ArrayList(...));实现同步
有一个capacity变量代表存储能力,当超过这个能力就需要扩容。


常用的add()就是在列表尾部添加一个元素
add(int, Object)指定添加元素的插入位置,这个操作就涉及到元素的移动了。
public void add(int index, E element) {
    rangeCheckForAdd(index);


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


以上两个方法就可能会涉及到扩容,扩容主要方法:
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);
}


remove(int index)方法删除指定index的元素,涉及元素移动。


还有一个注意的点就是
modCount这个变量
在类说明中或者代码都能看出,这个变量是记录列表结构的变动次数,在add,remove等方法都会被调用,而且使用的地方是在迭代器遍历时。
生成迭代器时,初始化一个expectedModCount变量,初始值为modCount
每次next()获取元素后,都会判断一下expectedModCount和modCount是否相同,如果不同则抛出异常,此举是防止在遍历时,因为多线程等因素ArrayList被改变了。

你可能感兴趣的:(Java,源码)