1. 成员变量
//默认初始容量
private static final int DEFAULT_CAPACITY = 10;
//共享空实例对象,用这个表示数组为空
private static final Object[] EMPTY_ELEMENTDATA = {};
//共享空实例对象,用这个表示该ArrayList对象是调用默认构造方法创建数组容器
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//数组容器,用于存储数据
transient Object[] elementData;
//容器大小
private int size;
//容器最大大小
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
2. 构造方法
public ArrayList() {
//默认构造,DEFAULTCAPACITY_EMPTY_ELEMENTDATA就是个共享的空数组,所以我们用默认构造创建ArrayList时是空的。
//只有这种方式创建的ArrayList,elementData等于DEFAULTCAPACITY_EMPTY_ELEMENTDATA
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
public ArrayList(int initialCapacity) {
// 如果以带初始化大小的方式创建,初始数组是有长度的
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
public ArrayList(Collection<? extends E> c) {
//以带初始化内容方式创建
elementData = c.toArray();
if ((size = elementData.length) != 0) {
//判断elementData的类型,如果不为Object[].class才会赋值,如果为Object[].class表示上面toArray方法执行错误了。需要利用这个方法赋值
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// 如果传入数组为空的话,和第二种构造方法传入0是一样的
this.elementData = EMPTY_ELEMENTDATA;
}
}
- add方法
//直接添加一个数据
public boolean add(E e) {
modCount++;
//调用了add(e, elementData, size)
add(e, elementData, size);
return true;
}
//指定位置添加一个数据
public void add(int index, E element) {
//下标检查
rangeCheckForAdd(index);
modCount++;
final int s;
Object[] elementData;
if ((s = size) == (elementData = this.elementData).length)
elementData = grow();
System.arraycopy(elementData, index,
elementData, index + 1,
s - index);
elementData[index] = element;
size = s + 1;
}
private void add(E e, Object[] elementData, int s) {
//如果添加的位置等于当前容器长度,容器扩容,一般为1.5倍
if (s == elementData.length)
elementData = grow();
elementData[s] = e;
size = s + 1;
}
- grow扩容
private Object[] grow() {
//这里代码上理解扩容1格,其实不一定
return grow(size + 1);
}
private Object[] grow(int minCapacity) {
//将容器扩容指定大小
return elementData = Arrays.copyOf(elementData,newCapacity(minCapacity));
}
private int newCapacity(int minCapacity) {
//旧容器大小
int oldCapacity = elementData.length;
//新容器大小为旧容器的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
//如果新容器的大小小于需求大小,一般发生在第一次添加数据时
if (newCapacity - minCapacity <= 0) {
//如果是以默认构造方法创建的
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
return Math.max(DEFAULT_CAPACITY, minCapacity);
if (minCapacity < 0) // minCapacity<0表示溢出了
throw new OutOfMemoryError();
return minCapacity;
}
return (newCapacity - MAX_ARRAY_SIZE <= 0)
? newCapacity
: hugeCapacity(minCapacity);
}
- remove方法
//删除指定对象
public boolean remove(Object o) {
final Object[] es = elementData;
final int size = this.size;
int i = 0;
//跳出循环还能这样用啊
found: {
if (o == null) {
for (; i < size; i++)
if (es[i] == null)
break found;
} else {
for (; i < size; i++)
//这里需要注意的一点,arrayList,remove(Object o)方法删除的是值相同的元素,且只能删除第一个
if (o.equals(es[i]))
break found;
}
return false;
}
fastRemove(es, i);
return true;
}
private void fastRemove(Object[] es, int i) {
modCount++;
final int newSize;
//fastRemove方法其实只是将该元素后面的元素全部进一位,最后一位置为null,同时size-1;
if ((newSize = size - 1) > i)
System.arraycopy(es, i + 1, es, i, newSize - i);
es[size = newSize] = null;
}
//删除指定下标,这个挺简单的。
public E remove(int index) {
//检查下标是否越界
Objects.checkIndex(index, size);
final Object[] es = elementData;
@SuppressWarnings("unchecked") E oldValue = (E) es[index];
fastRemove(es, index);
return oldValue;
}
5. 迭代器
//常见的获取迭代器的方法
public Iterator<E> iterator() {
//返回了一个内部类
return new Itr();
}
//迭代器内部类,实现了Iterator接口
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
// prevent creating a synthetic constructor
Itr() {}
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
//next方法其实是就是返回数组的当前下标对象
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();
//每次next游标都会+1
cursor = i + 1;
//每次next都会将lastRet赋值
return (E) elementData[lastRet = i];
}
//之所以迭代器可以正确在遍历中删除元素,就是因为它删除的不是自己的元素,下标不像for循环每次都会自增,而是始终保持在最后一个。。。我们for循环相当于自己给自己做手术,迭代器相当于医生给自己做手术。
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
//删除当前下标元素
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
@Override
public void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
final int size = ArrayList.this.size;
int i = cursor;
if (i < size) {
final Object[] es = elementData;
if (i >= es.length)
throw new ConcurrentModificationException();
for (; i < size && modCount == expectedModCount; i++)
action.accept(elementAt(es, i));
// update once at end to reduce heap write traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}
}
//这个方法是用来判断数组有没有在其他地方被修改了,modCount是数组的修改次数,expectedModCount是迭代器保存的数组修改次数,这两个如果不一样说明数组在其他地方修改了,就会报错
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}