源码阅读—List分支-ArrayList

来源:互联网 发布:linux 打开终端快捷键 编辑:程序博客网 时间:2024/06/05 07:12
基本数据结构是数组。


实现了List接口,允许元素为空。
extends AbstractList<E> implements List<E>, 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被改变了。