2015.01.11&12
By 970655147
其实, 之前查看jdk的这个api文档的时候, 一直都是查看的是各个常用的类的方法啊, 那些, 但是一直没有什么闲心来看看, 前面的关于对于这个类的说明, 这些, 今天 没事看了一看, 感觉这个写的真不错。。
贴出来 分享一下, 就像讲的貌似是类声明的部分的注释吧
备注 : 其中[ sth ]中的内容, 是我自己添加的
List 接口的大小可变数组的实现。实现了所有可选列表操作,并允许包括 null 在内的所有元素。除了实现 List 接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。(此类大致上等同于 Vector 类,除了此类是不同步的。)
size、isEmpty、get、set、iterator 和 listIterator 操作都以固定时间运行。add 操作以分摊的固定时间 运行,也就是说,添加 n 个元素需要 O(n) 时间。其他所有操作都以线性时间运行(大体上讲)。与用于 LinkedList 实现的常数因子相比,此实现的常数因子较低。
每个 ArrayList 实例都有一个容量。该容量是指用来存储列表元素的数组的大小。它总是至少等于列表的大小。随着向 ArrayList 中不断添加元素,其容量也自动增长。并未指定增长策略的细节,因为这不只是添加元素会带来分摊固定时间开销那样简单。
[这里 我的理解 : 增长的策略并没有指定, 因此添加一个元素的时候, 还有一定的常量时间分摊开销]
在添加大量元素前,应用程序可以使用 ensureCapacity 操作来增加 ArrayList 实例的容量。这可以减少递增式再分配的数量。
注意,此实现不是同步的。如果多个线程同时访问一个 ArrayList 实例,而其中至少一个线程从结构上修改了列表,那么它必须 保持外部同步。(结构上的修改是指任何添加或删除一个或多个元素的操作,或者显式调整底层数组的大小;仅仅设置元素的值不是结构上的修改。 [这个貌似就是modCount的修改规范])这一般通过对自然封装该列表的对象进行同步操作来完成。如果不存在这样的对象,则应该使用 Collections.synchronizedList 方法将该列表“包装”起来。这最好在创建时完成,以防止意外对列表进行不同步的访问:
List list = Collections.synchronizedList(new ArrayList(...));
此类的 iterator 和 listIterator 方法返回的迭代器是快速失败的:在创建迭代器之后,除非通过迭代器自身的 remove 或 add 方法从结构上对列表进行修改,否则在任何时间以任何方式对列表进行修改,迭代器都会抛出 ConcurrentModificationException。因此,面对并发的修改,迭代器很快就会完全失败,而不是冒着在将来某个不确定时间发生任意不确定行为的风险。
注意,迭代器的快速失败行为无法得到保证,因为一般来说,不可能对是否出现不同步并发修改做出任何硬性保证。快速失败迭代器会尽最大努力抛出 ConcurrentModificationException。因此,为提高这类迭代器的正确性而编写一个依赖于此异常的程序是错误的做法:迭代器的快速失败行为应该仅用于检测 bug。
此类是 Java Collections Framework 的成员。
start ->
, 大家可以看看注释
/**
* Resizable-array implementation of the List interface. Implements
* all optional list operations, and permits all elements, including
* 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. (This class is roughly equivalent to
* Vector, except that it is unsynchronized.)
*
* The size, isEmpty, get, set,
* iterator, and listIterator operations run in constant
* time. The add operation runs in amortized constant time,
* that is, adding n elements requires O(n) time. All of the other operations
* run in linear time (roughly speaking). The constant factor is low compared
* to that for the LinkedList implementation.
*
*
Each ArrayList instance has a capacity. The capacity is
* the size of the array used to store the elements in the list. It is always
* at least as large as the list size. As elements are added to an ArrayList,
* its capacity grows automatically. 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. 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. (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. This is best done at creation time, to prevent accidental
* unsynchronized access to the list:
* List list = Collections.synchronizedList(new ArrayList(...));
*
* name="fail-fast"/>
* The iterators returned by this class's {@link #iterator() iterator} and
* {@link #listIterator(int) listIterator} methods are fail-fast:
* 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}. 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.
* 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.
*
*
This class is a member of the
* "{@docRoot}/../technotes/guides/collections/index.html">
* Java Collections Framework.
*
* @author Josh Bloch
* @author Neal Gafter
* @see Collection
* @see List
* @see LinkedList
* @see Vector
* @since 1.2
*/
public class ArrayList extends AbstractList
implements List, RandomAccess, Cloneable, java.io.Serializable
// 默认的capacity
// 空集合元素 [没有初始容量的话, 令elementData为这个集合]
// 存储集合中的数据的数组 [这个属性时transient的, 默认序列化的时候, 是不会写出这个数据的, 但是ArrayList重写了writeObject, readObject[从而保证了数据的完整] ]
// 当前有多少个元素
private static final int DEFAULT_CAPACITY = 10;
private static final Object[] EMPTY_ELEMENTDATA = {};
private transient Object[] elementData;
private int size;
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
}
public ArrayList() {
super();
this.elementData = EMPTY_ELEMENTDATA;
}
public ArrayList(Collection extends E> c) {
elementData = c.toArray();
size = elementData.length;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
public boolean add(E e) {
// 确保elementData能容纳下 e
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
ArrayList. ensureCapacityInternal(int minCapacity)
private void ensureCapacityInternal(int minCapacity) {
if (elementData == EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
ArrayList. ensureExplicitCapacity(int minCapacity)
private void ensureExplicitCapacity(int minCapacity) {
// 对集合进行了改变,改变计数器加1
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
ArrayList. grow(int minCapacity)
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
// 默认的增长弧度 3/2
// 一次grow 至少增长原长度的1/2
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
// 如果newCapacity大于MAX_ARRAY_SIZE
// minCapacity 可能大于MAX_ARRAY_SIZE, 也有可能不大于MAX_ARRAY_SIZE
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
// 将elementData中的数据拷贝到新数组中
elementData = Arrays.copyOf(elementData, newCapacity);
}
ArrayList.hugeCapacity(int minCapacity)
private static int hugeCapacity(int minCapacity) {
// 如果minCapacity<0 表示minCapacity已经溢出了[超过了Integer.MAX_VALUE]
// 从这里可以看出ArrayList的最大容量可能是Integer.MAX_VALUE 可能是应为size是Integer.MAX_VALUE的吧
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
public void add(int index, E element) {
// 边界校验
// 确保可以空间足够
// 依次将大于index的元素拷贝到index+1处
// 插入新元素
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1, size - index);
elementData[index] = element;
size++;
}
ArrayList. rangeCheckForAdd(int index)
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
public boolean addAll(Collection extends E> c) {
// 确保空间足够, 并将c中的所有元素复制到当前ArrayList
// 更新size
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
public boolean addAll(int index, Collection extends E> c) {
// 校验索引
// 将index以及其之后的元素向后移动c.size个元素
// 然后将c的所有元素复制到当前ArrayList的index处开始
rangeCheckForAdd(index);
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments 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;
}
public int indexOf(Object o) {
// 如果o是null 用==判定 否则用equals判定
// 没找到相同的返回-1
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;
}
public int lastIndexOf(Object o) {
// 和上面的indexOf方法类似 不过从最后一个元素开始查找
// 没找到相同的返回-1
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;
}
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
ArrayList. rangeCheck(int index)
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
public E set(int index, E element) {
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
public E remove(int index) {
// 更新modCount, 并将index之后的所有元素向前移动一位, 并更新size
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
public boolean remove(Object o) {
// 如果o为null 使用==判定, 否则使用equals判定
// 找到 o元素所在的索引, 并删除该元素
// 如果有该元素 返回true, 否则 返回false
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;
}
ArrayList. fastRemove(int index)
private void fastRemove(int index) {
// 与上面的remove(int index)基本上一致, 区别在于是否返回index出之前的元素
modCount++;
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
}
protected void removeRange(int fromIndex, int toIndex) {
// 将toIdx以及其之后的元素向前移动(toIdx – fromIdx)位, 将toIdx之后的元素置空, 更新size
modCount++;
int numMoved = size - toIndex;
System.arraycopy(elementData, toIndex, elementData, fromIndex,
numMoved);
// clear to let GC do its work
int newSize = size - (toIndex-fromIndex);
for (int i = newSize; i < size; i++) {
elementData[i] = null;
}
size = newSize;
}
public void trimToSize() {
// modCount用于记录集合是被修改了多少次了 主要用于并发修改异常的判断
// 如果元素没有装满数组 则截断至元素的个数
modCount++;
if (size < elementData.length) {
elementData = Arrays.copyOf(elementData, size);
}
}
Arrays. copyOf(T[] original, int newLength)
public static T[] copyOf(T[] original, int newLength) {
return (T[]) copyOf(original, newLength, original.getClass());
}
Arrays. copyOf(U[] original, int newLength, Class extends T[]> newType)
public static <T,U> T[] copyOf(U[] original, int newLength, Class extends T[]> newType) {
// 复制orginal newLength个元素,最多original元素个数个元素到copy数组
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
System. arraycopy(Object src, int srcPos,Object dest, int destPos, int length);
public static native void arraycopy(Object src, int srcPos,Object dest, int destPos, int length);
public void ensureCapacity(int minCapacity) {
// 如果elementData为EMPTY_ELEMENTDATA 则最小的capacity为DEFAULT_CAPACITY [刚创建ArrayList的时候elementData=EMPTY_ELEMENTDATA]
// 否则 如果minCapacity大于0, 则尝试更新容量
int minExpand = (elementData != EMPTY_ELEMENTDATA)
// any size if real element table
? 0
// larger than default for empty table. It's already supposed to be
// at default size.
: DEFAULT_CAPACITY;
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity);
}
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public Object clone() {
try {
// 调用AbstractList.clone() 然后为其填充数据
@SuppressWarnings("unchecked")
ArrayList v = (ArrayList) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
}
public Object[] toArray() {
// 返回elementData的一个副本
return Arrays.copyOf(elementData, size);
}
@SuppressWarnings("unchecked")
public T[] toArray(T[] a) {
// 如果a的长度不够 返回一个elementData的复本
if (a.length < size)
// Make a new array of a's runtime type, but my contents:
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
System.arraycopy(elementData, 0, a, 0, size);
// 如果a的长度大于size
// 令a[size]==null 为了确保链表的结尾, 判断链表的长度
// (This is useful in determining the length of the
* list only if the caller knows that the list does not contain any null elements.)
if (a.length > size)
a[size] = null;
return a;
}
@SuppressWarnings("unchecked")
E elementData(int index) {
return (E) elementData[index];
}
ArrayList. removeAll(Collection> c)
public boolean removeAll(Collection> c) {
return batchRemove(c, false);
}
ArrayList. batchRemove(Collection> c, boolean complement)
private boolean batchRemove(Collection> c, boolean complement) {
final Object[] elementData = this.elementData;
int r = 0, w = 0;
boolean modified = false;
try {
// 对elementData进行遍历
// 如果complement为true 保留c中包含的elementData的元素,否则保留c不中包含的elementData的元素
// 如果抛出异常 将r及之后的元素拷贝回去
// 对w之后的元素 置空对象的引用 让gc回收对象
// 至少有一个元素没有 复制那么 整个集合就modified
for (; r < size; r++)
if (c.contains(elementData[r]) == complement)
elementData[w++] = elementData[r];
} finally {
// Preserve behavioral compatibility with AbstractCollection,
// even if c.contains() throws.
if (r != size) {
System.arraycopy(elementData, r,
elementData, w,
size - r);
w += size - r;
}
if (w != size) {
// clear to let GC do its work
for (int i = w; i < size; i++)
elementData[i] = null;
modCount += size - w;
size = w;
modified = true;
}
}
return modified;
}
public boolean retainAll(Collection> c) {
return batchRemove(c, true);
}
public ListIterator listIterator(int index) {
// RangeCheck
if (index < 0 || index > size)
throw new IndexOutOfBoundsException("Index: "+index);
// 返回index处数据的ListIterator
return new ListItr(index);
}
private class ListItr extends Itr implements ListIterator<E> {
ListItr(int index) {
super();
cursor = index;
}
public boolean hasPrevious() {
return cursor != 0;
}
public int nextIndex() {
return cursor;
}
public int previousIndex() {
return cursor - 1;
}
// 这个方法和next()方法类似 参见next()
@SuppressWarnings("unchecked")
public E previous() {
checkForComodification();
int i = cursor - 1;
if (i < 0)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i;
return (E) elementData[lastRet = i];
}
public void set(E e) {
// 如果刚刚并没有删除/添加 数据 那么没有数据可以修改 抛出异常
// ArrayList.set(index, element)不会修改modCount 所有这里不必更新expectedModCount
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.set(lastRet, e);
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
public void add(E e) {
checkForComodification();
try {
// 在当前cursor处 添加一个元素
// 更新cursor,lastSet和expectedModCount
int i = cursor;
ArrayList.this.add(i, e);
cursor = i + 1;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
}
public Iterator iterator() {
return new Itr();
}
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;
// 是否还有下一个元素
public boolean hasNext() {
return cursor != size;
}
// 返回下一个元素
@SuppressWarnings("unchecked")
public E next() {
// 并发修改检查
// 如果cursor越界 抛出异常
// cursor迭代
// 记录这一次返回的cursor 在下一次迭代中就是上一次的cursor 用于删除验证
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];
}
public void remove() {
// 如果并没有进行迭代 或者刚删除数据 那么没有什么数据可以删除 抛出异常
// 并发修改检查
// 删除上一次迭代取出的数据 cursor -= 1 将lastSet置为-1
// 修改iterator的expectedModCount 以免下次操作的时候抛出并发修改异常
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
// 检测除了迭代器修改集合 还有没有其他的因素在修改集合
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
public List subList(int fromIndex, int toIndex) {
// RangeCheck
subListRangeCheck(fromIndex, toIndex, size);
return new SubList(this, 0, fromIndex, toIndex);
}
ArrayList.subListRangeCheck(int fromIndex, int toIndex, int 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 + ")");
}
// 一个子List 里面几乎实现了ArrayList的所有操作[委托给当前ArrayList对象操作] 对SubList对象的操作会影响到当前ArrayList对象
private class SubList extends AbstractList<E> implements RandomAccess {
private final AbstractList parent;
private final int parentOffset;
private final int offset;
int size;
SubList(AbstractList 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;
}
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;
}
public E get(int index) {
rangeCheck(index);
checkForComodification();
return ArrayList.this.elementData(offset + index);
}
public int size() {
checkForComodification();
return this.size;
}
public void add(int index, E e) {
rangeCheckForAdd(index);
checkForComodification();
parent.add(parentOffset + index, e);
// 同步this.modCount 以免下次操作发生并发修改异常
this.modCount = parent.modCount;
this.size++;
}
public E remove(int index) {
rangeCheck(index);
checkForComodification();
E result = parent.remove(parentOffset + index);
//
this.modCount = parent.modCount;
this.size--;
return result;
}
protected void removeRange(int fromIndex, int toIndex) {
checkForComodification();
parent.removeRange(parentOffset + fromIndex,
parentOffset + toIndex);
//
this.modCount = parent.modCount;
this.size -= toIndex - fromIndex;
}
public boolean addAll(Collection extends E> c) {
return addAll(this.size, c);
}
public boolean addAll(int index, Collection extends E> c) {
rangeCheckForAdd(index);
int cSize = c.size();
if (cSize==0)
return false;
checkForComodification();
parent.addAll(parentOffset + index, c);
//
this.modCount = parent.modCount;
this.size += cSize;
return true;
}
// 当前SubList的迭代器
public Iterator iterator() {
return listIterator();
}
// 当前SubList的ListIterator
public ListIterator listIterator(final int index) {
checkForComodification();
rangeCheckForAdd(index);
final int offset = this.offset;
return new ListIterator() {
int cursor = index;
int lastRet = -1;
int expectedModCount = ArrayList.this.modCount;
public boolean hasNext() {
return cursor != SubList.this.size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= SubList.this.size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (offset + i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[offset + (lastRet = i)];
}
public boolean hasPrevious() {
return cursor != 0;
}
@SuppressWarnings("unchecked")
public E previous() {
checkForComodification();
int i = cursor - 1;
if (i < 0)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (offset + i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i;
return (E) elementData[offset + (lastRet = i)];
}
public int nextIndex() {
return cursor;
}
public int previousIndex() {
return cursor - 1;
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
SubList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = ArrayList.this.modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
public void set(E e) {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.set(offset + lastRet, e);
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
public void add(E e) {
checkForComodification();
try {
int i = cursor;
SubList.this.add(i, e);
cursor = i + 1;
lastRet = -1;
expectedModCount = ArrayList.this.modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (expectedModCount != ArrayList.this.modCount)
throw new ConcurrentModificationException();
}
};
}
public List subList(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size);
return new SubList(this, offset, fromIndex, toIndex);
}
private void rangeCheck(int index) {
if (index < 0 || index >= this.size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private void rangeCheckForAdd(int index) {
if (index < 0 || index > this.size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+this.size;
}
private void checkForComodification() {
if (ArrayList.this.modCount != this.modCount)
throw new ConcurrentModificationException();
}
}
->
end, 其实就是一个线性表, 难点在于理解扩容机制, 以及Iterator, ListIterator, SubList 三个内部类
java.util.Vector 和ArrayList的代码逻辑基本一致, 不过Vector的业务方法[或者访问了多线程共享域的委托的方法]均是synchronized的 [线程安全]
Vector 与ArrayList的一些业务方法名命名方式不同, 后者更加简洁一些
Vector 与ArrayList还有一个区别在于扩容的方式, 前者可以指定扩容的增量, 如果没有指定默认为扩容为原来容量的2倍, 而ArrayList的扩容为原来的容量的3 / 2