/**
* Resizable-array implementation of the List interface.
* 可调整大小的数组的List的实现
*
* Implements all optional list operations, and permits all elements, including null.
* 实现了所有可选的List操作,以及允许任何元素,包括null。
*
* In addition to implementing the List interface, this class provides methods to manipulate the size of the array that is used internally to store the list.
* 除了实现List接口外,这个类还提供了一些方法来操作内部用于存储列表的数组的大小。
* (This class is roughly equivalent to Vector, except that it is unsynchronized.)
* 这个类大致相当于Vector,只是它是不同步的
*
* The size, isEmpty, get, set, iterator, and listIterator operations run in constant time.
* size、isEmpty、get、set、迭代器和listIterator操作以恒定时间运行。
*
* The add operation runs in amortized constant time, that is, adding n elements requires O(n) time.
* add操作需要O(n)的时间,其中n是添加的元素的数量。
*
* All of the other operations run in linear time (roughly speaking).
* 其他操作以线性时间运行(近似地)。
*
* The constant factor is low compared to that for the LinkedList implementation.
* 这个常数因子与LinkedList实现相比要低得多。
*
*
* Each ArrayList instance has a capacity.
* 每个ArrayList实例都有一个容量。
*
* The capacity is the size of the array used to store the elements in the list.
* 这个capacity是存储列表中元素的数组的大小。
*
* It is always at least as large as the list size.
* 容量至少是列表的大小。
*
* As elements are added to an ArrayList, its capacity grows automatically.
* 当元素添加到ArrayList时,它的容量会自动增长。
*
* The details of the growth policy are not specified beyond the fact that adding an element has constant amortized time cost.
* 除了增加一个要素具有恒定的摊余时间成本这一事实之外,没有具体说明增长政策的细节。
*
* An application can increase the capacity of an ArrayList instance before adding a large number of elements using the ensureCapacity operation.
* 应用程序可以使用ensureCapacity操作在添加大量元素之前增加ArrayList实例的容量。
*
* This may reduce the amount of incremental reallocation.
* 这可能减少增量重新分配。
*
* Note that this implementation is not synchronized.
* 这个实现不是线程安全的。
*
* If multiple threads access an ArrayList instance concurrently,
* and at least one of the threads modifies the list structurally, it
* must be synchronized externally.
* 如果多个线程同时访问一个ArrayList实例,并且至少有一个线程修改了列表的结构,那么它必须在外部同步。
*
* (A structural modification is
* any operation that adds or deletes one or more elements, or explicitly
* resizes the backing array; merely setting the value of an element is not
* a structural modification.)
* 结构修改指的是任何操作,添加或删除一个或多个元素,或修改了数组的大小;仅仅修改了集合中元素的值不是结构修改。
*
* This is typically accomplished by synchronizing on some object that naturally encapsulates the list.
* 通常操作是将列表包装在某些对象上,以确保在外部进行同步。
*
* If no such object exists, the list should be "wrapped" using the {@link Collections#synchronizedList Collections.synchronizedList} method.
* 如果不存在这样的对象,则应使用 {@linkCollections#synchronizedListCollections.synchronizedList}方法。
* This is best done at creation time, to prevent accidental unsynchronized access to the list:
* 最好在创建时执行此操作,以防止意外地对列表进行不同步的访问:
*
* List list = Collections.synchronizedList(new ArrayList(...));
*
* fail-fast快速失败
*
* The iterators returned by this class's {@link #iterator() iterator} and
* {@link #listIterator(int) listIterator} methods are fail-fast
* 通过iterator()和listIterator(int)方法返回的迭代器具有“快速失败”特性。
*
* if the list is structurally modified at any time after the iterator is
* created, in any way except through the iterator's own
* {@link ListIterator#remove() remove} or
* {@link ListIterator#add(Object) add} methods, the iterator will throw a
* {@link ConcurrentModificationException}.
* 如果在创建迭代器之后以任何方式(除了通过迭代器自身的remove()或add(Object)方法)对列表进行结构性修改,那么迭代器将会抛出一个ConcurrentModificationException异常。
*
* Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.
* 因此,面对并发修改,迭代器会迅速而干净地失败,而不是冒着在未来不确定的时间出现任意、不确定行为的风险。
*
* Note that the fail-fast behavior of an iterator cannot be guaranteed
* as it is, generally speaking, impossible to make any hard guarantees in the
* presence of unsynchronized concurrent modification.
* 无法保证绝对的快速失败:尽管快速失败机制试图在检测到并发修改时立即抛出异常,但在非同步并发修改的情况下,由于线程间的竞态条件等因素,理论上不可能对快速失败行为做出严格的保证。
* Fail-fast iterators throw {@code ConcurrentModificationException} on a best-effort basis.
* 尽力而为的原则:快速失败的迭代器会在尽最大努力的基础上抛出ConcurrentModificationException异常。这意味着虽然设计上期望在并发修改发生时能及时发现并抛出异常,但不能确保每次都能准确捕获到所有可能的并发修改情况。
*
* Therefore, it would be wrong to write a program that depended on this
* exception for its correctness: the fail-fast behavior of iterators
* should be used only to detect bugs.
* 正确使用快速失败机制:开发人员不应依赖于快速失败异常来确保程序逻辑的正确性。也就是说,不应该编写这样的代码:其正常运行的前提是必须抛出ConcurrentModificationException。这是因为快速失败行为并不能作为并发编程中的一种安全机制来使用。
*
* This class is a member of the
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
* Java Collections Framework</a>.
*
* @author Josh Bloch
* @author Neal Gafter
* @see Collection
* @see List
* @see LinkedList
* @see Vector
* @since 1.2
*/
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private static final long serialVersionUID = 8683452581122892189L;
/**
* Default initial capacity.
* 默认初始容量
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* Shared empty array instance used for empty instances.
* 这是共享的空数组实例,用于表示没有任何元素的ArrayList。当ArrayList被创建且未指定初始容量时,并不会立即分配实际的数据存储空间,而是引用这个空数组。
*/
private static final Object[] EMPTY_ELEMENTDATA = {
};
/**
* Shared empty array instance used for default sized empty instances.
* 这也是一个共享的空数组实例,但它专门用于表示默认大小(即初始容量为0)的空ArrayList
*
* We distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when first element is added.
* EMPTY_ELEMENTDATA区分的主要目的是为了在扩容时准确知道应该将数组容量扩大到多大
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {
};
/**
* The array buffer into which the elements of the ArrayList are stored.
* ArrayList的元素都会存储在这个数组缓冲区中
*
* The capacity of the ArrayList is the length of this array buffer.
* 属猪的数组缓冲区的容量就是ArrayList的容量。
*
* Any empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA will be expanded to DEFAULT_CAPACITY when the first element is added.
* 如果ArrayList为空,并且其内部的 elementData 变量引用的是 DEFAULTCAPACITY_EMPTY_ELEMENTDATA 这个空数组实例,在添加第一个元素时,ArrayList会将其容量自动扩展到默认容量(DEFAULT_CAPACITY)
*
* 说明:
* transient 关键字表明该字段不会被序列化,即在将对象转换为字节流进行持久化存储或网络传输时,不会包含此字段的数据
* 通常情况下成员变量会声明为私有(private)以保护其内部状态不被外部直接访问,但在这里故意没有将其设置为私有的原因是便于嵌套类(nested class)访问这个变量
*/
transient Object[] elementData; // non-private to simplify nested class access
/**
* The size of the ArrayList (the number of elements it contains).
* ArrayList的大小(即包含的元素个数)
*
* @serial
*/
private int size;
/**
* Constructs an empty list with the specified initial capacity.
* 构建一个空的ArrayList,指定初始容量
*
* @param initialCapacity list的初始容量
* @throws IllegalArgumentException 如果初始容量一个负数抛出异常
*/
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);
}
}
/**
* Constructs an empty list with an initial capacity of ten.
* 构建一个空的ArrayList,初始容量为10
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/**
* Constructs a list containing the elements of the specified
* collection, in the order they are returned by the collection's
* iterator.
* 构建一个ArrayList,包含指定集合中的所有元素,按照集合的迭代器返回的顺序
*
* @param c 构建list元素的集合
* @throws NullPointerException 如果目标集合是null,则抛出NullPointerException异常
*/
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
// Java1.6 以前可能存在c.toArray()不是Object[]的问题https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6260652
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
/**
* Trims the capacity of this ArrayList instance to be the list's current size.
* 整理容量,将ArrayList的容量调整到当前大小
* An application can use this operation to minimize the storage of an ArrayList instance.
* 系统可以使用此方法来最小化ArrayList实例的存储。
*/
public void trimToSize() {
// ArrayList被修改的次数
modCount++;
// size是当前元素数量,当前元素数量小于底层数据数组(elementData),则说明有收缩的空间
if (size < elementData.length) {
// 当元素为0时,设置为预定的空数组,释放原数组空间,
// 否则调用Arrays.copyOf方法,将底层数组复制到新数组中,并返回新数组
elementData = (size == 0)
? EMPTY_ELEMENTDATA
: Arrays.copyOf(elementData, size);
}
}
/**
* Increases the capacity of this ArrayList instance, if necessary, to ensure that it can hold at least the number of elements specified by the minimum capacity argument.
* 确保ArrayList的容量至少能容纳minCapacity个元素
*
* @param minCapacity the desired minimum capacity,所需的最小容量
*/
public void ensureCapacity(int minCapacity) {
// 最小扩展容量minExpand
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
// any size if not default element table
// 如果当前不是默认的元素数组,说明ArrayListy已经被初始化,将minExpand设置为0,说明任何大小都进行扩容
? 0
// larger than default for default empty table. It's already supposed to be at default size.
// 默认的空数组,表明ArrayList还未真正分配过容量,这时minExpand被设置为DEFAULT_CAPACITY,它是ArrayList初始容量的默认值
: DEFAULT_CAPACITY;
// 需要的最小容量,大于当前最小扩展容量,则进行扩容
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity);
}
}
// 用于计算ArrayList需要的实际容量。
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
// 调用calculateCapacity方法计算实际需要的容量,并将结果传递给ensureExplicitCapacity方法,触发扩容操作
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private void ensureExplicitCapacity(int minCapacity) {
// 集合操作数增加
modCount++;
// overflow-conscious code
// 此处是考虑溢出的情况,详情可以参考使用:minCapacity - elementData.length > 0 对于minCapacity > elementData.length,虽然逻辑上相同
// 但是在实际计算机中会有溢出的情况,第一种写法可以避免一部分溢出的问题
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
/**
* The maximum size of array to allocate.
* array的最大值
* Some VMs reserve some header words in an array.
* 一些VM在数组中保留一些头信息,
*
* Attempts to allocate larger arrays may result in OutOfMemoryError: Requested array size exceeds VM limit
* 超过VM限制可能会抛出的OutOfMemoryError: Requested array size exceeds VM limit
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/**
* Increases the capacity to ensure that it can hold at least the number of elements specified by the minimum capacity argument.
* 增加容量,确保至少能容纳minCapacity个元素
*
* @param minCapacity the desired minimum capacity
*/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
// 即将现有容量增加1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 如果新的容量仍不足以满足要求,因此将 newCapacity 直接设置为 minCapacity。
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
// 防止数组容量过大造成整数溢出,调用hugeCapacity(minCapacity) 来处理超大容量的需求,该方法会返回一个合适的最大容量值
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
// minCapacity 往往接近于当前 ArrayList 的大小(size),通过这种方式扩容既能满足未来存储需求,又不会过度分配内存,从而提高了效率
elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
// 整数溢出
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
// 如果minCapacity大于MAX_ARRAY_SIZE,则返回Integer的最大值Integer.MAX_VALUE,此时vm会抛出OutOfMemoryError: Requested array size exceeds VM limit
Integer.MAX_VALUE :、
// 如果minCapacity不大于MAX_ARRAY_SIZE,则直接返回MAX_ARRAY_SIZE作为最大的允许容量值,ArrayList将扩容到这个大小
MAX_ARRAY_SIZE;
}
/**
* Returns the number of elements in this list.
* 返回集合中元素的个数
*
* @return the number of elements in this list
*/
public int size() {
return size;
}
/**
* Returns true if this list contains no elements.
* 返回true,如果集合中元素个数为0
*
* @return true if this list contains no elements
*/
public boolean isEmpty() {
return size == 0;
}
/**
* Returns true if this list contains the specified element.
* 返回true,如果集合中包含指定的元素
*
* More formally, returns true if and only if this list contains at least one element e such that (o==null ? e==null : o.equals(e)).
* 更正式的,如果集合中包含至少一个元素e,满足o==null ? e==null : o.equals(e),则返回true;
*
* @param o element whose presence in this list is to be tested
* @return true if this list contains the specified element
*/
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
/**
* Returns the index of the first occurrence of the specified element in this list, or -1 if this list does not contain the element.
* 返回索引的第一个出现指定的元素的索引,如果不包含指定的元素,则返回-1
*
* More formally, returns the lowest index i such that (o==null ? get(i)==null : o.equals(get(i))), or -1 if there is no such index.
* 更正式的,返回满足o==null ? get(i)==null : o.equals(get(i))的最小索引i,如果不存在满足条件的索引,则返回-1
*/
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;
}
/**
* Returns the index of the last occurrence of the specified element in this list, or -1 if this list does not contain the element.
* 返回最后一个出现指定的元素的索引,如果不包含指定的元素,则返回-1
*
* More formally, returns the highest index i such that (o==null ? get(i)==null : o.equals(get(i))), or -1 if there is no such index.
* 更正式的,返回满足o==null ? get(i)==null : o.equals(get(i))的最大索引i,如果不存在满足条件的索引,则返回-1
*/
public int lastIndexOf(O