/**
* List 接口的大小可变数组的实现。实现了所有可选列表操作,并允许包括 null 在内的所有元素。
* 除了实现 List 接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。
* (此类大致上等同于 Vector 类,除了此类是不同步的。)
* size、isEmpty、get、set、iterator 和 listIterator 操作都以固定时间运行。
* add 操作以分摊的固定时间 运行,也就是说,添加 n 个元素需要 O(n) 时间。
* 其他所有操作都以线性时间运行(大体上讲)。
* 与用于 LinkedList 实现的常数因子相比,此实现的常数因子较低。
* 每个 ArrayList 实例都有一个容量。该容量是指用来存储列表元素的数组的大小。
* 它总是至少等于列表的大小。随着向 ArrayList 中不断添加元素,其容量也自动增长。
* 并未指定增长策略的细节,因为这不只是添加元素会带来分摊固定时间开销那样简单。
* 在添加大量元素前,应用程序可以使用 ensureCapacity 操作来增加 ArrayList 实例的容量。
* 这可以减少递增式再分配的数量。
* 注意,此实现不是同步的。如果多个线程同时访问一个 ArrayList 实例,
* 而其中至少一个线程从结构上修改了列表,那么它必须 保持外部同步。
* (结构上的修改是指任何添加或删除一个或多个元素的操作,或者显式调整底层数组的大小;
* 仅仅设置元素的值不是结构上的修改。)这一般通过对自然封装该列表的对象进行同步操作来完成。
* 如果不存在这样的对象,则应该使用 Collections.synchronizedList 方法将该列表“包装”起来。
* 这最好在创建时完成,以防止意外对列表进行不同步的访问:
* List list = Collections.synchronizedList(new ArrayList(...));
* 此类的 iterator 和 listIterator 方法返回的迭代器是快速失败的:
* 在创建迭代器之后,除非通过迭代器自身的 remove 或 add 方法从结构上对列表进行修改,
* 否则在任何时间以任何方式对列表进行修改,迭代器都会抛出 ConcurrentModificationException。
* 因此,面对并发的修改,迭代器很快就会完全失败,而不是冒着在将来某个不确定时间发生任意不确定行为的风险。
* 注意,迭代器的快速失败行为无法得到保证,因为一般来说,不可能对是否出现不同步并发修改做出任何硬性保证。
* 快速失败迭代器会尽最大努力抛出 ConcurrentModificationException。
* 因此,为提高这类迭代器的正确性而编写一个依赖于此异常的程序是错误的做法:
* 迭代器的快速失败行为应该仅用于检测 bug。
* 此类是 Java Collections Framework 的成员。
*/
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
/*
* 继承 AbstractList类,获取get()、size()方法
* 实现List接口
* 实现RandomAccess接口
* 实现Cloneable接口
* 实现Serializable接口,序列化
*/
private static final long serialVersionUID = 8683452581122892189L;
// 默认初始容量。
private static final int DEFAULT_CAPACITY = 10;
// 用于空实例的共享空数组实例。
private static final Object[] EMPTY_ELEMENTDATA = {};
/*
* 用于默认大小的空实例的共享空数组实例。
* 我们将其与EMPTY_ELEMENTDATA区分开来,以了解在添加第一个元素时要膨胀多少。
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/*
* 存储ArrayList元素的数组缓冲区。ArrayList的容量是这个数组缓冲区的长度。
* 当添加第一个元素时,任何带有elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA的
* 空ArrayList都将扩展为DEFAULT_CAPACITY。
*/
transient Object[] elementData;// 非私有,可以简化嵌套类访问
// ArrayList的大小(它包含的元素的数量)。
private int size;
/**
* 构造一个具有指定初始容量的空列表
* @param initialCapacity 列表的初始容量
*/
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {// 初始容量大于0,实例化elementData
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {// 初始容量等于0,用默认数组实例
this.elementData = EMPTY_ELEMENTDATA;
} else {// 如果指定的初始容量为负
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
/**
* 构造一个初始容量为 10 的空列表
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/**
* 构造一个包含指定 collection 的元素的列表,
* 这些元素是按照该 collection 的迭代器返回它们的顺序排列的。
* @param c 其元素将放置在此列表中的 collection
*/
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();// 获取包含此 collection 中所有元素的数组
if ((size = elementData.length) != 0) {
// c.toArray可能(不正确)不返回Object[]
if (elementData.getClass() != Object[].class)
// 复制elementData为object[]
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// 用空数组替换.
this.elementData = EMPTY_ELEMENTDATA;
}
}
/**
* 将此 ArrayList 实例的容量调整为列表的当前大小。
* 应用程序可以使用此操作来最小化 ArrayList 实例的存储量。
*/
public void trimToSize() {
modCount++;
if (size < elementData.length) {
elementData = (size == 0)
? EMPTY_ELEMENTDATA
: Arrays.copyOf(elementData, size);
}
}
/**
* 如有必要,增加此 ArrayList 实例的容量,以确保它至少能够容纳最小容量参数所指定的元素数。
* @param minCapacity 所需的最小容量
*/
public void ensureCapacity(int minCapacity) {
//如果想要的最小容量大于最小扩容量,则使用想要的最小容量。
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
// 如果不是默认元素表,则为任意大小
? 0
// 对于默认空表,大于默认值。它已经是默认大小了。
: DEFAULT_CAPACITY;
if (minCapacity > minExpand) { // 增加容量
ensureExplicitCapacity(minCapacity);
}
}
/**
* 返回DEFAULT_CAPACITY和minCapacity中较大的一个
* @param elementData
* @param minCapacity 所需的最小容量
* @return
*/
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
// 返回DEFAULT_CAPACITY和minCapacity中较大的一个。
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
/**
* 比较DEFAULT_CAPACITY和minCapacity中的大小,增加集合容量,只供内部使用
* @param minCapacity 所需的最小容量
*/
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
/**
* 增加集合容量,如果指定的最小容量大于数组缓冲区当前的长度,则扩容,只供内部使用
* @param minCapacity 所需的最小容量
*/
private void ensureExplicitCapacity(int minCapacity) {
modCount++;// 已从结构上修改 此列表的次数,此字段由 iterator 和 listIterator 方法返回的迭代器和列表迭代器实现使用。
// 确保指定的最小容量 > 数组缓冲区当前的长度
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
/*
* 要分配的数组的最大大小。一些VMs在数组中保留一些头信息。
* 尝试分配更大的数组可能会导致OutOfMemoryError:请求的数组大小超过VM限制
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/**
* 增加容量,以确保它至少可以容纳最小容量参数指定的元素数量。
* @param minCapacity 最小化所需的最小容量
*/
private void grow(int minCapacity) {
int oldCapacity = elementData.length;// 数组缓冲区当前的长度
int newCapacity = oldCapacity + (oldCapacity >> 1); // 扩容。新的容量=当前容量+当前容量/2.即将当前容量增加一半。
if (newCapacity - minCapacity < 0) // 如果扩容后的容量还是小于想要的最小容量
newCapacity = minCapacity;// 将扩容后的容量再次扩容为想要的最小容量
if (newCapacity - MAX_ARRAY_SIZE > 0)// 如果扩容后的容量大于临界值,则进行大容量分配
newCapacity = hugeCapacity(minCapacity);
// minCapacity通常接近于size,所以这是一个优势:
elementData = Arrays.copyOf(elementData, newCapacity);
}
/**
* 容量分配,如果扩容后的容量大于临界值,则进行大容量分配
* @param minCapacity 最小化所需的最小容量
* @return
*/
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
/**
* 返回此列表中的元素数
*/
public int size() {
return size;
}
/**
* 如果此列表中没有元素,则返回 true
* 覆盖:如果此列表中没有元素,则返回 true
*/
public boolean isEmpty() {
return size == 0;
}
/**
* 如果此列表中包含指定的元素,则返回 true。更确切地讲,
* 当且仅当此列表包含至少一个满足 (o==null ? e==null : o.equals(e)) 的元素 e 时,则返回 true。
* 覆盖:类 AbstractCollection<E> 中的 contains
* @param o 测试此列表中是否存在的元素
*/
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
/**
* 返回此列表中首次出现的指定元素的索引,或如果此列表不包含元素,则返回 -1。
* 更确切地讲,返回满足 (o==null ? get(i)==null : o.equals(get(i))) 的最低索引 i ,
* 如果不存在此类索引,则返回 -1。
* 覆盖:类 AbstractList<E> 中的 indexOf
* @param o 搜索的元素
*/
public int indexOf(Object o) {
if (o == null) { // 为空
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else { // 非空
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
/**
* 返回此列表中最后一次出现的指定元素的索引,或如果此列表不包含索引,则返回 -1。
* 更确切地讲,返回满足 (o==null ? get(i)==null : o.equals(get(i))) 的最高索引 i,
* 如果不存在此类索引,则返回 -1。
* 覆盖:类 AbstractList<E> 中的 lastIndexOf
* @param o 要搜索的元素
*/
public int lastIndexOf(Object o) {
if (o == null) { // 为空
for (int i = size-1; i >= 0; i--)
if (elementData[i]==null)
return i;
} else { // 非空
for (int i = size-1; i >= 0; i--)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
/**
* 返回此 ArrayList 实例的浅拷贝。(不复制这些元素本身。)
* 覆盖:类 Object 中的 clone
* @return 此 ArrayList 实例的一个副本
*/
public Object clone() {
try {
ArrayList<?> v = (ArrayList<?>) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// 这不应该发生,因为我们可以Cloneable
throw new InternalError(e);
}
}
/**
* 按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组。
* 由于此列表不维护对返回数组的任何引用,,因而它将是“安全的”。
* (换句话说,此方法必须分配一个新的数组)。因此,调用者可以自由地修改返回的数组。
* 此方法担当基于数组的 API 和基于 collection 的 API 之间的桥梁。
* 覆盖:类 AbstractCollection<E> 中的 toArray
* @return 包含此列表中所有元素的数组(按适当顺序)
*/
public Object[] toArray() {
return Arrays.copyOf(elementData, size);
}
/**
* 按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组;
* 返回数组的运行时类型是指定数组的运行时类型。如果指定的数组能容纳列表,则将该列表返回此处。
* 否则,将分配一个具有指定数组的运行时类型和此列表大小的新数组。
* 如果指定的数组能容纳队列,并有剩余的空间(即数组的元素比队列多),
* 那么会将数组中紧接 collection 尾部的元素设置为 null。
* (仅 在调用者知道列表中不包含任何 null 元素时才能用此方法确定列表长度)。
* 覆盖:类 AbstractCollection<E> 中的 toArray
* @param a 要在其中存储列表元素的数组(如果它足够大);否则,为此分配一个具有相同运行时类型的新数组。
* @return 包含列表元素的数组
*/
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
if (a.length < size)
// 创建一个新的数组的a的运行时类型,但我的内容:
// 复制elementData数组,截取或用 null 填充(如有必要),以使副本具有size的长度。
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
// 从数组elementData中复制一个数组a,复制从0开始,到数组elementData的size-1结束。
System.arraycopy(elementData, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
// 位置访问操作
/**
* 位置访问操作
* @param index 索引位置
* @return
*/
@SuppressWarnings("unchecked")
E elementData(int index) {
return (E) elementData[index];
}
/**
* 返回此列表中指定位置上的元素
* @param index 要返回元素的索引
* @return 此列表中指定位置上的元素
*/
public E get(int index) {
// 检查给定的索引是否在范围内。
rangeCheck(index);
// 返回此列表中指定位置上的元素
return elementData(index);
}
/**
* 用指定的元素替代此列表中指定位置上的元素。
* 覆盖:类 AbstractList<E> 中的 set
* @param index 要替代的元素的索引
* @param element 存储在指定位置上的元素
* @return 以前位于该指定位置上的元素
*/
public E set(int index, E element) {
// 检查给定的索引是否在范围内。
rangeCheck(index);
// 获取此列表中指定位置上的元素
E oldValue = elementData(index);
// 替换值
elementData[index] = element;
// 返回以前位于该指定位置上的元素
return oldValue;
}
/**
* 将指定的元素添加到此列表的尾部。
* 覆盖:类 AbstractList<E> 中的 add
* @param e 要添加到此列表中的元素
* @return true(按照 Collection.add(E) 的指定)
*/
public boolean add(E e) {
// 比较DEFAULT_CAPACITY和size + 1中的大小,增加集合容量
ensureCapacityInternal(size + 1); // 增量modCount ! !
elementData[size++] = e;
return true;
}
/**
* 将指定的元素插入此列表中的指定位置。
* 向右移动当前位于该位置的元素(如果有)以及所有后续元素(将其索引加 1)。
* 覆盖:类 AbstractList<E> 中的 add
* @param index 指定元素所插入位置的索引
* @param element 要插入的元素
*/
public void add(int index, E element) {
// 检查给定的索引是否在范围内。
rangeCheckForAdd(index);
// 比较DEFAULT_CAPACITY和size + 1中的大小,增加集合容量
ensureCapacityInternal(size + 1); // 增量modCount ! !
// 复制数组
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
// 放入元素
elementData[index] = element;
// 增加ArrayList的size
size++;
}
/**
* 移除此列表中指定位置上的元素。向左移动所有后续元素(将其索引减 1)。
* 覆盖:类 AbstractList<E> 中的 remove
* @param index 要移除的元素的索引
* @return 从列表中移除的元素
*/
public E remove(int index) {
// 检查给定的索引是否在范围内。
rangeCheck(index);
modCount++; // 增量modCount
E oldValue = elementData(index); // 获取原来的值
int numMoved = size - index - 1;
if (numMoved > 0) // 复制数组
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // 清除,让GC完成它的工作
return oldValue;
}
/**
* 移除此列表中首次出现的指定元素(如果存在)。如果列表不包含此元素,则列表不做改动。
* 更确切地讲,移除满足 (o==null ? get(i)==null : o.equals(get(i))) 的最低索引的元素(如果存在此类元素)。
* 如果列表中包含指定的元素,则返回 true(或者等同于这种情况:如果列表由于调用而发生更改,则返回 true)。
* 覆盖:类 AbstractCollection<E> 中的 remove
* @param o 要从此列表中移除的元素(如果存在)
* @return 如果此列表包含指定的元素,则返回 true
*/
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;
}
/**
* 私有移除方法,该方法跳过边界检查,不返回已删除的值。
* @param index 要移除的元素的索引
*/
private void fastRemove(int index) {
modCount++;
int numMoved = size - index - 1;
if (numMoved > 0) // 复制数组
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null;// 清除,让GC完成它的工作
}
/**
* 移除此列表中的所有元素。此调用返回后,列表将为空。
* 覆盖:类 AbstractList<E> 中的 clear
*/
public void clear() {
modCount++; // 增量modCount
// 清除,让GC完成它的工作
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
/**
* 按照指定 collection 的迭代器所返回的元素顺序,将该 collection 中的所有元素添加到此列表的尾部。
* 如果正在进行此操作时修改指定的 collection ,那么此操作的行为是不确定的。
* (这意味着如果指定的 collection 是此列表且此列表是非空的,那么此调用的行为是不确定的)。
* 覆盖:类 AbstractCollection<E> 中的 addAll
* @param c 包含要添加到此列表中的元素的 collection
* @return 如果此列表由于调用而发生更改,则返回 true
*/
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // 增量modCount
// 复制数组
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
/**
* 从指定的位置开始,将指定 collection 中的所有元素插入到此列表中。
* 向右移动当前位于该位置的元素(如果有)以及所有后续元素(增加其索引)。
* 新元素将按照指定 collection 的迭代器所返回的元素顺序出现在列表中。
* 覆盖:类 AbstractList<E> 中的 addAll
* @param index 插入指定 collection 中的首个元素的位置索引
* @param c 包含要添加到此列表中元素的 collection
* @return
*/
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);// 检查给定的索引是否在范围内。
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // 增量modCount
int numMoved = size - index;
if (numMoved > 0) // 在范围之内,复制数组
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved);
// 复制数组
System.arraycopy(a, 0, elementData, index, numNew);
size += numNew;
return numNew != 0;
}
/**
* 移除列表中索引在 fromIndex(包括)和 toIndex(不包括)之间的所有元素。
* 向左移动所有后续元素(减小其索引)。此调用将列表缩短了 (toIndex - fromIndex) 个元素。
* (如果 toIndex==fromIndex,则此操作无效。)
* @param fromIndex 要移除的首个元素的索引
* @param toIndex 最后一个要移除的元素后面那个元素的索引
*/
protected void removeRange(int fromIndex, int toIndex) {
modCount++; // 增量modCount
int numMoved = size - toIndex;
// 复制数组
System.arraycopy(elementData, toIndex, elementData, fromIndex,
numMoved);
// 清除,让GC完成它的工作
int newSize = size - (toIndex-fromIndex);
for (int i = newSize; i < size; i++) { // 移除
elementData[i] = null;
}
size = newSize;
}
/**
* 检查给定的索引是否在范围内。如果不是,则抛出适当的运行时异常。
* 这个方法不检查索引是否为负:它总是在数组访问之前立即使用,
* 如果索引为负,就会抛出ArrayIndexOutOfBoundsException。
* @param index
*/
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
/**
* 调用add()方法和addAll()方法时,使用的rangeCheck版本。
* @param index 需要检查的索引位置
*/
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
/**
* 构造IndexOutOfBoundsException详细信息。
* 在错误处理代码的许多可能重构中,这个“大纲”在服务器和客户端vm上执行得最好。
* @param index 需要检查的索引位置
* @return
*/
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+size;
}
/**
* 从该列表中删除指定集合中包含的所有元素。
* 覆盖:类AbstractCollection<E>中的removeAll
* @param c 集合,其中包含要从此列表中删除的元素
* @return 如果此list因调用而更改,返回true
*/
public boolean removeAll(Collection<?> c) {
// 检查指定的对象引用是否为空。
Objects.requireNonNull(c);
return batchRemove(c, false);
}
/**
* 只保留此列表中指定集合中包含的元素。换句话说,从该列表中删除指定集合中不包含的所有元素。
* 覆盖:类AbstractCollection<E>中的retainAll
* @param c 集合,其中包含要保留在此列表中的元素
* @return 如果此list因调用而更改,返回true
*/
public boolean retainAll(Collection<?> c) {
// 检查指定的对象引用是否为空。
Objects.requireNonNull(c);
return batchRemove(c, true);
}
/**
* 私有删除工具类
* @param c 集合,其中包含要从此列表中删除的元素
* @param complement true:从该列表中删除指定集合中不包含的所有元素;
* false:从该列表中删除指定集合中包含的所有元素
* @return 如果此list因调用而更改,返回true
*/
private boolean batchRemove(Collection<?> c, boolean complement) {
final Object[] elementData = this.elementData;
int r = 0, w = 0;
boolean modified = false;
try {
for (; r < size; r++)
if (c.contains(elementData[r]) == complement)
elementData[w++] = elementData[r];
} finally {
// 即使c.contains()抛出,也要保持与AbstractCollection的行为兼容性。
if (r != size) { // 复制数组
System.arraycopy(elementData, r,
elementData, w,
size - r);
w += size - r;
}
if (w != size) {
// 清除,让GC完成它的工作
for (int i = w; i < size; i++)
elementData[i] = null;
modCount += size - w;
size = w;
modified = true;
}
}
return modified;
}
/**
* 将ArrayList实例的状态保存到流中(即序列化它)。
* @param s
* @serialData 支持ArrayList实例的数组的长度(int)被发出,然后它的所有元素(每个对象)以适当的顺序发出。
* @throws java.io.IOException
*/
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{
// 写出元素计数和所有隐藏的东西
int expectedModCount = modCount;
// 将当前类的非静态和非瞬态字段写入此流。
s.defaultWriteObject();
// 写出大小作为与克隆行为相容性的容量()
// 写入一个 32 位的 int 值。
s.writeInt(size);
// 按适当的顺序写出所有的元素。
for (int i=0; i<size; i++) {
s.writeObject(elementData[i]);
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
/**
* 从流中重新构造ArrayList实例(即反序列化它)。
* @param s
* @throws java.io.IOException
* @throws ClassNotFoundException
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
elementData = EMPTY_ELEMENTDATA;
// 读取大小,以及任何隐藏的东西
s.defaultReadObject();
// 读取容量
// 读取一个 32 位的 int 值
s.readInt(); // 忽略了
if (size > 0) {
// 类似于clone(),根据大小而不是容量分配数组
int capacity = calculateCapacity(elementData, size);
SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class, capacity);
ensureCapacityInternal(size);
Object[] a = elementData;
// 按正确的顺序读取所有元素。
for (int i=0; i<size; i++) {
a[i] = s.readObject();
}
}
}
/**
* 从列表中指定的位置开始,对该列表中的元素(以适当的顺序)返回一个列表迭代器。
* 指定的索引指示对next的初始调用将返回的第一个元素。
* 对previous的初始调用将返回具有指定index - 1的元素。
* 覆盖:AbstractList<E>类的listIterator
* @param index 从列表迭代器返回的第一个元素的索引(通过调用next)
* @return 从列表中指定的位置开始,对该列表中的元素进行列表迭代器(按正确的顺序)
*/
public ListIterator<E> listIterator(int index) {
if (index < 0 || index > size)
throw new IndexOutOfBoundsException("Index: "+index);
return new ListItr(index);
}
/**
* 返回列表中元素的列表迭代器(按正确的顺序)。
* 返回的列表迭代器是快速失败的。
* 覆盖:AbstractList<E>类的listIterator
* @return 对列表中的元素进行列表迭代器(按正确的顺序)
*/
public ListIterator<E> listIterator() {
return new ListItr(0);
}
/**
* 以适当的顺序返回列表中元素的迭代器。
* 返回的迭代器是快速失败的。
* 覆盖:AbstractList<E>类的iterator
* @return 以适当的顺序对列表中的元素进行迭代
*/
public Iterator<E> iterator() {
return new Itr();
}
/**
* An optimized version of AbstractList.Itr
*/
private class Itr implements Iterator<E> {
int cursor; // 要返回的下一个元素的索引
int lastRet = -1; // 返回的最后一个元素的索引;如果没有为-1
int expectedModCount = modCount;
Itr() {}
/**
* 如果仍有元素可以迭代,则返回 true。
*/
public boolean hasNext() {
return cursor != size;
}
/**
* 返回迭代的下一个元素
*/
@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];
}
/**
* 从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。
* 每次调用 next 只能调用一次此方法。
* 如果进行迭代时用调用此方法之外的其他方式修改了该迭代器所指向的 collection,
* 则迭代器的行为是不确定的
*/
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();
}
}
/**
* 从基础集合中删除此迭代器返回的最后一个元素(可选操作)。
* 对next()的每次调用只能调用此方法一次。
* 如果在迭代过程中以除调用此方法之外的任何方式修改底层集合,则迭代器的行为是未指定的。
*/
@Override
@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer<? super E> consumer) {
// 检查指定的对象引用是否为空。
Objects.requireNonNull(consumer);
final int size = ArrayList.this.size;
int i = cursor;
if (i >= size) {
return;
}
final Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
// 对(E) elementData[i++]执行此操作
consumer.accept((E) elementData[i++]);
}
// 在迭代结束时更新一次,以减少堆写流量
cursor = i;
lastRet = i - 1;
// 并发检查
checkForComodification();
}
/**
* 检查已从结构上修改 此列表的次数是否不一致,用于并发检查
*/
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
/**
* 一个优化的AbstractList.ListItr版本
*/
private class ListItr extends Itr implements ListIterator<E> {
ListItr(int index) {
super();
cursor = index;
}
/**
* 要返回的下一个元素的索引非0,则返回 true。
*/
public boolean hasPrevious() {
return cursor != 0;
}
/**
* 返回的下一个元素的索引。
*/
public int nextIndex() {
return cursor;
}
/**
* 返回对 previous 的后续调用所返回元素的索引。(如果列表迭代器在列表的开始,则返回 -1)。
* @param 对 previous 的后续调用所返回元素的索引,如果列表迭代器在列表的开始,则返回 -1。
*/
public int previousIndex() {
return cursor - 1;
}
/**
* 返回列表中的前一个元素。可以重复调用此方法来迭代列表,
* 或混合调用 next 来前后移动(注意交替调用 next 和 previous 将重复返回相同的元素)。
* return 列表中的上一个元素。
*/
@SuppressWarnings("unchecked")
public E previous() {
// 并发检查
checkForComodification();
int i = cursor - 1;
if (i < 0)
throw new NoSuchElementException();
// 获取当前ArrayList的元素
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i;
return (E) elementData[lastRet = i];
}
/**
* 用指定元素替换 next 或 previous 返回的最后一个元素(可选操作)。
* @param e 用于替换 next 或 previous 返回的最后一个元素的元素。
*/
public void set(E e) {
if (lastRet < 0)
throw new IllegalStateException();
// 并发检查
checkForComodification();
try {
// 用e替代此列表中的lastRet。
// 调用当前ArrayList的set()方法
ArrayList.this.set(lastRet, e);
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
/**
* 将指定的元素插入列表(可选操作)。
* @param e 要插入的元素
*/
public void add(E e) {
// 并发检查
checkForComodification();
try {
int i = cursor;
// 调用当前ArrayList的add()方法
ArrayList.this.add(i, e);
cursor = i + 1;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
}
/**
* 返回指定的fromIndex(包含)和toIndex(排除)之间的列表部分的视图。
* (如果fromIndex和toIndex相等,返回的列表为空。)返回的列表由这个列表支持,
* 因此返回列表中的非结构性更改反映在这个列表中,反之亦然。返回的列表支持所有可选的列表操作。
*
* 这种方法不需要显式的范围操作(数组中常见的那种类型)。
* 通过传递子列表视图而不是整个列表,任何期望列表的操作都可以作为范围操作使用。
* 例如,下面的习惯用法从列表中删除了一系列元素:
* list.subList(from, to).clear();
* 可以为indexOf(Object)和lastIndexOf(Object)构造类似的习惯用法,并且集合类中的所有算法都可以应用于子列表。
*
* 如果支持列表(即在结构上,除了通过返回的列表之外,可以以任何方式进行修改。
* 结构修改是指更改列表的大小,或者以某种方式干扰列表,从而导致正在进行的迭代可能产生不正确的结果。)
* 覆盖:AbstractList<E>的subList
* @param fromIndex 子列表的第一个元素的索引(包括)
* @param toIndex 子列表的最后一个元素的索引(不包括)
* @return 此列表中指定范围的视图
*/
public List<E> subList(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size);
return new SubList(this, 0, fromIndex, toIndex);
}
/**
* 私有工具类——校验参数
* @param fromIndex 子列表的起始位置(包括)
* @param toIndex 子列表的结束位置(不包括)
* @param size
*/
static void subListRangeCheck(int fromIndex, int toIndex, int size) {
if (fromIndex < 0)
throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
if (toIndex > size)
throw new IndexOutOfBoundsException("toIndex = " + toIndex);
if (fromIndex > toIndex)
throw new IllegalArgumentException("fromIndex(" + fromIndex +
") > toIndex(" + toIndex + ")");
}
private class SubList extends AbstractList<E> implements RandomAccess {
private final AbstractList<E> parent;
private final int parentOffset;
private final int offset;
int size;
SubList(AbstractList<E> parent,
int offset, int fromIndex, int toIndex) {
this.parent = parent;
this.parentOffset = fromIndex;
this.offset = offset + fromIndex;
this.size = toIndex - fromIndex;
this.modCount = ArrayList.this.modCount;
}
/**
* 用指定元素替换列表中指定位置的元素(可选操作)。
* @param index 要替换的元素的索引
* @param e 要在指定位置存储的元素
* @return 以前在指定位置的元素
*/
public E set(int index, E e) {
// 检查给定的索引是否在范围内。
rangeCheck(index);
// 并发检查
checkForComodification();
// 获取旧值
E oldValue = ArrayList.this.elementData(offset + index);
// 替换新值
ArrayList.this.elementData[offset + index] = e;
// 返回旧值
return oldValue;
}
/**
* 返回列表中指定位置的元素
* @param index 要返回的元素的索引
* @return 列表中指定位置的元素
*/
public E get(int index) {
// 检查给定的索引是否在范围内。
rangeCheck(index);
// 并发检查
checkForComodification();
// 获取元素
return ArrayList.this.elementData(offset + index);
}
/**
* 返回当前SubList中的元素数。
*/
public int size() {
// 并发检查
checkForComodification();
return this.size;
}
/**
* 在父列表的指定位置插入指定元素(可选操作)。
* @param index 要在其中插入指定元素处的索引
* @param e 要插入的元素
*/
public void add(int index, E e) {
// 检查给定的索引是否在范围内。
rangeCheckForAdd(index);
// 并发检查
checkForComodification();
// 调用父列表的add()方法
parent.add(parentOffset + index, e);
this.modCount = parent.modCount;
this.size++;
}
/**
* 移除列表中指定位置的元素(可选操作)。
* 返回从列表中移除的元素。
* @param index 要移除的元素的索引
* @return 以前在指定位置的元素
*/
public E remove(int index) {
// 检查给定的索引是否在范围内。
rangeCheck(index);
// 并发检查
checkForComodification();
// 调用父列表的remove()方法
E result = parent.remove(parentOffset + index);
this.modCount = parent.modCount;
this.size--;
return result;
}
/**
* 从此列表中移除索引在 fromIndex(包括)和 toIndex(不包括)之间的所有元素。
* @param fromIndex 要移除的第一个元素的索引。
* @param toIndex 要移除的最后一个元素之后的索引。
*/
protected void removeRange(int fromIndex, int toIndex) {
// 并发检查
checkForComodification();
// 调用父列表的removeRange()方法
parent.removeRange(parentOffset + fromIndex,
parentOffset + toIndex);
this.modCount = parent.modCount;
this.size -= toIndex - fromIndex;
}
/**
* 将指定 collection 中的所有元素都插入到列表中。
* @param c 包含要添加到此列表的元素的 collection
* @return 如果此列表由于调用而发生更改,则返回 true
*/
public boolean addAll(Collection<? extends E> c) {
return addAll(this.size, c);
}
/**
* 将指定 collection 中的所有元素都插入到列表中。
* @param index 将指定 collection 的第一个元素所插入位置的索引
* @param c 包含要添加到此列表的元素的 collection
* @return 如果此列表由于调用而发生更改,则返回 true
*/
public boolean addAll(int index, Collection<? extends E> c) {
// 检查给定的索引是否在范围内。
rangeCheckForAdd(index);
int cSize = c.size();
if (cSize==0)
return false;
// 并发检查
checkForComodification();
// 调用父列表的addAll()方法
parent.addAll(parentOffset + index, c);
this.modCount = parent.modCount;
this.size += cSize;
return true;
}
/**
* 返回以恰当顺序在此列表的元素上进行迭代的迭代器
* @return 在此 subList 中的元素上进行迭代的迭代器。
*/
public Iterator<E> iterator() {
return listIterator();
}
/**
* 返回列表中元素的列表迭代器(按适当顺序),从列表的指定位置开始。
* 指定的索引表示 next 的初始调用所返回的第一个元素。
* @param index 从列表迭代器返回的第一个元素的索引(通过调用 next 方法)
* @return 此列表中元素的列表迭代器(按适当顺序),从列表中的指定位置开始
*/
public ListIterator<E> listIterator(final int index) {
// 并发检查
checkForComodification();
// 检查给定的索引是否在范围内。
rangeCheckForAdd(index);
final int offset = this.offset;
return new ListIterator<E>() {
int cursor = index;
int lastRet = -1;
int expectedModCount = ArrayList.this.modCount;
public boolean hasNext() {
return cursor != SubList.this.size;
}
/**
* 返回当前ArrayList中的下一个元素
*/
@SuppressWarnings("unchecked")
public E next() {
// 并发检查
checkForComodification();
int i = cursor;
if (i >= SubList.this.size)
throw new NoSuchElementException();
// 获取当前ArrayList对象的元素
Object[] elementData = ArrayList.this.elementData;
if (offset + i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[offset + (lastRet = i)];
}
/**
* 返回cursor != 0
*/
public boolean hasPrevious() {
return cursor != 0;
}
/**
* 返回当前父列表中的前一个元素
*/
@SuppressWarnings("unchecked")
public E previous() {
// 并发检查
checkForComodification();
int i = cursor - 1;
if (i < 0)
throw new NoSuchElementException();
// 获取当前ArrayList对象的元素
Object[] elementData = ArrayList.this.elementData;
if (offset + i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i;
return (E) elementData[offset + (lastRet = i)];
}
/**
* 如果存在剩余元素,对其执行给定操作,返回true;否则返回false。
* @param consumer
*/
@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer<? super E> consumer) {
// 检查指定的对象引用是否为空。
Objects.requireNonNull(consumer);
// 获取当前SubList对象的大小
final int size = SubList.this.size;
int i = cursor;
if (i >= size) {
return;
}
// 获取当前ArrayList对象的元素
final Object[] elementData = ArrayList.this.elementData;
if (offset + i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
// 对((E) elementData[offset + (i++)]执行此操作
consumer.accept((E) elementData[offset + (i++)]);
}
// 在迭代结束时更新一次,以减少堆写流量
lastRet = cursor = i;
// 并发检查
checkForComodification();
}
/**
* 返回cursor。
*/
public int nextIndex() {
return cursor;
}
/**
* 返回cursor - 1。
*/
public int previousIndex() {
return cursor - 1;
}
/**
* 移除元素
*/
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
// 并发检查
checkForComodification();
try {
// 调用当前Sublist的remove()方法
SubList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
// 获取当前ArrayList对象的元素
expectedModCount = ArrayList.this.modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
/**
* 替换元素 。
* @param e 替换元素
*/
public void set(E e) {
if (lastRet < 0)
throw new IllegalStateException();
// 并发检查
checkForComodification();
try {
//调用当前ArrayList.set()方法
ArrayList.this.set(offset + lastRet, e);
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
/**
* 将指定的元素插入SubList列表(可选操作)。
* @param e 要插入的元素
*/
public void add(E e) {
// 并发检查
checkForComodification();
try {
int i = cursor;
// 调用当前Sublist的add()方法
SubList.this.add(i, e);
cursor = i + 1;
lastRet = -1;
// 获取当前ArrayList对象的元素
expectedModCount = ArrayList.this.modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
/**
* 检查已从结构上修改 此列表的次数是否不一致,用于并发检查
*/
final void checkForComodification() {
if (expectedModCount != ArrayList.this.modCount)
throw new ConcurrentModificationException();
}
};
}
/**
* 返回子列表列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。
* @param fromIndex subList的首个元素的索引(包括)
* @param toIndex subList的最后一个元素的索引(不包括)
*/
public List<E> subList(int fromIndex, int toIndex) {
// 校验参数
subListRangeCheck(fromIndex, toIndex, size);
return new SubList(this, offset, fromIndex, toIndex);
}
/**
* 检查给定的索引是否在范围内。如果不是,则抛出适当的运行时异常。
* 这个方法不检查索引是否为负:它总是在数组访问之前立即使用,
* 如果索引为负,就会抛出ArrayIndexOutOfBoundsException。
* @param index
*/
private void rangeCheck(int index) {
if (index < 0 || index >= this.size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
/**
* 调用add()方法和addAll()方法时,使用的rangeCheck版本。
* @param index 需要检查的索引位置
*/
private void rangeCheckForAdd(int index) {
if (index < 0 || index > this.size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
/**
* 构造IndexOutOfBoundsException详细信息。
* @param index 需要检查的索引位置
* @return
*/
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+this.size;
}
/**
* 检查已从结构上修改 此列表的次数是否不一致,用于并发检查
*/
private void checkForComodification() {
if (ArrayList.this.modCount != this.modCount)
throw new ConcurrentModificationException();
}
/**
* 返回当前ArrayList中的元素的Spliterator。
*/
public Spliterator<E> spliterator() {
// 并发检查
checkForComodification();
return new ArrayListSpliterator<E>(ArrayList.this, offset,
offset + this.size, this.modCount);
}
}
/**
* 为Iterable的每个元素执行给定的操作,直到处理完所有元素或该操作抛出异常为止。
* 除非实现类另有指定,否则操作将按照迭代顺序执行(如果指定了迭代顺序)。
* 由操作引发的异常被转发给调用方。
* 覆盖:Iterable<T>的forEach
* @param action 为每个元素执行的操作
*/
@Override
public void forEach(Consumer<? super E> action) {
// 检查指定的对象引用是否为空。
Objects.requireNonNull(action);
final int expectedModCount = modCount;
@SuppressWarnings("unchecked")
final E[] elementData = (E[]) this.elementData;
final int size = this.size;
for (int i=0; modCount == expectedModCount && i < size; i++) {
// 对elementData[i]执行此操作
action.accept(elementData[i]);
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
/**
* 在列表里的元素上创建一个后期绑定和自动失效的Spliterator。
* Spliterator报告Spliterator.SIZED,Spliterator.SUBSIZED,Spliterator.ORDERED。
* 覆盖实现应该记录额外特征值的报告。
* 覆盖:Collection<E>的spliterator
*/
@Override
public Spliterator<E> spliterator() {
return new ArrayListSpliterator<>(this, 0, -1, 0);
}
/**
* 基于索引的2乘2的延迟初始化Spliterator
*/
static final class ArrayListSpliterator<E> implements Spliterator<E> {
/*
* 如果ArrayLists是不可变的,或者在结构上是不可变的(没有添加、删除等),
* 我们可以使用Arrays.spliterator实现它们的spliterator。
* 相反,在遍历过程中,我们在不牺牲性能的情况下尽可能多地检测干扰。
* 我们主要依赖于modCounts。
* 这些方法并不能保证检测并发性违规,而且有时对于线程内干扰过于保守,
* 但是能够检测出足够多的问题,在实践中是值得的。
* 为此,
* (1)延迟初始化fence和expectedModCount,直到需要提交到所检查的状态的最新点;从而提高精度。
* (这不适用于使用当前非延迟值创建spliterator的SubLists)。
* (2) 我们只在forEach(对性能最敏感的方法)的末尾执行一个ConcurrentModificationException检查。
* 在使用forEach时(与迭代器相反),我们通常只能在操作之后检测干扰,而不是在操作之前。
* 进一步的CME-触发检查适用于所有其他可能违反假设的情况,
* 例如null或太小的elementData数组(考虑到它的size()),这只可能是由于干扰而发生的。
* 这允许forEach的内部循环在不进行任何进一步检查的情况下运行,并简化了lambda解析。
* 虽然这确实需要许多检查,但请注意,在list.stream().forEach(a)的常见情况下,
* 除了在forEach本身内部之外,不会在其他任何地方进行检查或其他计算。
* 其他不常用的方法不能利用这些精简。
*/
private final ArrayList<E> list;
private int index; //当前索引,在advance/split时修改
private int fence; // 使用前为-1;最后一个索引
private int expectedModCount; // 初始化当fence设置的时候
/** 创建覆盖给定范围的新spliterator */
ArrayListSpliterator(ArrayList<E> list, int origin, int fence,
int expectedModCount) {
this.list = list; // 除非被遍历,否则为空
this.index = origin;
this.fence = fence;
this.expectedModCount = expectedModCount;
}
private int getFence() { // 在第一次使用时初始化fence的大小
int hi; // (在方法forEach中出现一个专门的变体)
ArrayList<E> lst;
if ((hi = fence) < 0) {
if ((lst = list) == null)
hi = fence = 0;
else {
expectedModCount = lst.modCount;
hi = fence = lst.size;
}
}
return hi;
}
/**
* 获取覆盖一半的元素的Spliterator
*/
public ArrayListSpliterator<E> trySplit() {
int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
return (lo >= mid) ? null : // 把范围分成两半,除非太小
new ArrayListSpliterator<E>(list, lo, index = mid,
expectedModCount);
}
/**
* 如果存在剩余元素,对其执行给定操作,返回true;否则返回false。
* @param action 动作
*/
public boolean tryAdvance(Consumer<? super E> action) {
if (action == null)
throw new NullPointerException();
int hi = getFence(), i = index;
if (i < hi) {
index = i + 1;
@SuppressWarnings("unchecked") E e = (E)list.elementData[i];
// 对e执行此操作
action.accept(e);
if (list.modCount != expectedModCount)
throw new ConcurrentModificationException();
return true;
}
return false;
}
/**
* 如果存在剩余元素,对其执行给定操作,返回true;否则返回false。
* @param action 动作
*/
public void forEachRemaining(Consumer<? super E> action) {
int i, hi, mc; // 从循环中获取访问和检查
ArrayList<E> lst; Object[] a;
if (action == null)
throw new NullPointerException();
if ((lst = list) != null && (a = lst.elementData) != null) {
if ((hi = fence) < 0) {
mc = lst.modCount;
hi = lst.size;
}
else
mc = expectedModCount;
if ((i = index) >= 0 && (index = hi) <= a.length) {
for (; i < hi; ++i) {
@SuppressWarnings("unchecked") E e = (E) a[i];
// 对e执行此操作
action.accept(e);
}
if (lst.modCount == mc)
return;
}
}
throw new ConcurrentModificationException();
}
/**
* 返回元素个数
*/
public long estimateSize() {
return (long) (getFence() - index);
}
/**
* 返回此Spliterator及其元素的一组特征。
* ORDERED(有序的)、SIZED(大小的)、SUBSIZED(已存在的值)
*/
public int characteristics() {
return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
}
}
/**
* 删除此集合中满足给定谓词的所有元素。
* 在迭代期间或由谓词引发的错误或运行时异常将被转发给调用方。
* 覆盖:Collection<E>接口的removeIf
* @param filter 对于要删除的元素返回true的谓词
* @return 如果删除了任何元素,则为true
*/
@Override
public boolean removeIf(Predicate<? super E> filter) {
// 检查指定的对象引用是否为空。
Objects.requireNonNull(filter);
// 确定要删除哪些元素在此阶段从筛选器谓词中抛出的任何异常都不会修改集合
int removeCount = 0;
final BitSet removeSet = new BitSet(size);
final int expectedModCount = modCount;
final int size = this.size;
for (int i=0; modCount == expectedModCount && i < size; i++) {
@SuppressWarnings("unchecked")
final E element = (E) elementData[i];
// 根据element计算此谓词,如果element与谓词匹配,则为真,否则为假
if (filter.test(element)) {
removeSet.set(i);
removeCount++;
}
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
// 将剩余的元素移动到被删除的元素留下的空间上
final boolean anyToRemove = removeCount > 0;
if (anyToRemove) {
final int newSize = size - removeCount;
for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {
// 获取下一个已清除位的索引。
i = removeSet.nextClearBit(i);
elementData[j] = elementData[i];
}
for (int k=newSize; k < size; k++) {
elementData[k] = null; // 让gc来完成它的工作
}
this.size = newSize;
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
modCount++;
}
return anyToRemove;
}
/**
* 将此列表中的每个元素替换为对该元素应用运算符的结果。
* 由操作员抛出的错误或运行时异常被转发给调用者。
* 覆盖:List<E>接口的replaceAll
* @param operator 应用于每个元素的运算符
*/
@Override
@SuppressWarnings("unchecked")
public void replaceAll(UnaryOperator<E> operator) {
// 检查指定的对象引用是否为空。
Objects.requireNonNull(operator);
final int expectedModCount = modCount;
final int size = this.size;
for (int i=0; modCount == expectedModCount && i < size; i++) {
// 获取函数的结果
elementData[i] = operator.apply((E) elementData[i]);
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
modCount++;
}
/**
* 根据指定比较器产生的顺序对列表进行排序。
*
* 使用指定的comparator(即c.compare(e1, e2)),
* 这个列表中的所有元素必须是相互可比的(对于列表中的任何元素e1和e2,都不能抛出ClassCastException)。
*
* 如果指定的比较器为null,那么这个列表中的所有元素都必须实现Comparable接口,并且应该使用元素的自然顺序。
*
* 此列表必须可修改,但不需要可调整大小。
* 覆盖:List<E>接口的sort
* @param c 用于比较列表元素的比较器。null值表示应该使用元素的自然顺序
*/
@Override
@SuppressWarnings("unchecked")
public void sort(Comparator<? super E> c) {
final int expectedModCount = modCount;
// 根据指定比较器(c)产生的顺序对elementData的指定范围[0 ,size ]进行排序。
Arrays.sort((E[]) elementData, 0, size, c);
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
modCount++;
}
}
参考:jdk 1.6 API
jdk 1.8 API