您的位置:首页 > 其它

ArrayList类注释翻译、源码分析

2017-06-30 10:40 459 查看
HashMap源码分析 :http://blog.csdn.net/disiwei1012/article/details/73530598

HashSet类注释翻译、fast-fail、源码分析 :http://blog.csdn.net/disiwei1012/article/details/73692452

Hashtable类注释翻译、源码分析 :http://blog.csdn.net/disiwei1012/article/details/73744181

一、类注释翻译

/**
* Resizable -array implementation of the <tt> List</tt> interface.  Implements
* all optional list operations, and permits all elements, including
* <tt>null </tt> .  In addition to implementing the <tt> List</tt> 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
* <tt>Vector </tt> , except that it is unsynchronized.)


用“可伸缩数组”来实现List接口。实现了所有List接口中的方法,并且允许存放所有元素,包括Null。

除了实现了List接口,本类还是提供操作数组大小的方法。(本类和Vector类似,只是本类是非同步的)

* <p>The <tt> size</tt> , <tt>isEmpty </tt> , <tt> get </tt>, <tt> set</tt> ,
* <tt>iterator </tt> , and <tt> listIterator </tt> operations run in constant
* time.  The <tt> add</tt> operation runs in <i>amortized constant time</i> ,
* 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 <tt> LinkedList</tt> implementation.


size、isEmpty、get、set、iterator、listIterator 这些操作用的时间是常量,(也就是说这些操作与元素的个数无关,操作的时间为o(1))。

add操作花费恒定分摊时间,也就是说插入n的元素的时间为o(n),其实分摊之后,也就相当于插入一个元素的时间为o(1)。

粗略的来说本类的其他操作都能在线性的时间内完成。(也就是说这些操作与元素的个成线性关系,操作的时间复杂度o(n))

What is meant by “Constant Amortized Time” when talking about time complexity of an algorithm?

https://stackoverflow.com/questions/200384/constant-amortized-time

* <p>Each <tt> ArrayList</tt> instance has a <i> capacity</i> .  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.


每个ArrayList实例都有一个容量。这个容量也就是用来存储元素的数组的大小,它至少等于list大小(list大小就是数组实际存放元素的个数)。

当一个元素被添加到集合中,这个集合的容量会自动增长。除了要求添加一个元素的效率为“恒定分摊时间”,对于具体实现的细节没有特别的要求。

* <p>An application can increase the capacity of an <tt> ArrayList</tt> instance
* before adding a large number of elements using the <tt> ensureCapacity</tt>
* operation.  This may reduce the amount of incremental reallocation.


在大批量插入元素前,使用ensureCapacity操作来增加集合的容量。这或许能够减少扩容之后新数组的大小。

【This may reduce the amount of incremental reallocation. 】这句的翻译感觉有点怪怪的。

* <p><strong>Note that this implementation is not synchronized.</strong>
* If multiple threads access an <tt> ArrayList</tt> instance concurrently,
* and at least one of the threads modifies the list structurally, it
* <i>must </i> 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.


此类是非同步的。如果多个线程同时操作ArrayList实例,至少一个线程结构性的修改,必须要保证线程的同步。

(结构性修改:增加或删除元素,或者调整数组大小,仅仅修改属性的值不属于结构性修改)

典型的实现是同步操作数组。

* 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: <pre>
*   List list = Collections.synchronizedList(new ArrayList(...));</pre>


如果这种对象不存在,又想同步集合,可以这样写:

Collections.synchronizedList(new ArrayList(...))


* <p><a name="fail-fast"/>
* The iterators returned by this class's {@link #iterator() iterator} and
* {@link #listIterator(int) listIterator} methods are <em> fail- fast </em>:
* 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.

* <p>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:  <i> the fail- fast behavior of iterators
* should be used only to detect bugs. </i>


关于fail-fast特性的介绍,请参考:http://www.cnblogs.com/skywang12345/p/3308762.html

二、源码分析

public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private static final long serialVersionUID = 8683452581122892189L;

/**
* 实际用来存储元素的地方,ArrayList的底层数据结构
* 该数组的大小即为ArrayList的容量
*/
private transient Object[] elementData ;

/**
* ArrayList存储元素个数
*
*/
private int size ;

/**
* 带初始容量initialCapacity的构造函数
*/
public ArrayList( int initialCapacity ) {
super ();
if (initialCapacity < 0)//如果初始容量小于0,抛出异常
throw new IllegalArgumentException( "Illegal Capacity: "+
initialCapacity );
创建底层数据,大小为initialCapacity
this.elementData = new Object[ initialCapacity];
}

/**
* 无参构造器,默认容量为10
*/
public ArrayList() {
this (10);
}

/**
* 创建一个参数为集合对象c的构造函数,将c中的元素添加到ArrayList中
* 通过迭代器返回的顺序和和c中的一样
* @throws 如果c为null,则抛出空指针异常
*/
public ArrayList(Collection<? extends E> c ) {
elementData = c .toArray();
size = elementData .length ;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
//toArray有可能不返回Object[],具体参考:http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6260652
//如果toArray方法返回的不是Object[],则将elementData转化成Object[],
//为ArrayList要能存放任何元素
if (elementData .getClass() != Object[]. class)
elementData = Arrays.copyOf( elementData , size , Object[]. class);
}

/**
* 缩短ArrayList容量大小和存储元素的个数相等
*/
public void trimToSize() {
//修改次数+1
modCount++;
int oldCapacity = elementData .length ;
if (size < oldCapacity ) {//如果当前数组大小>实际存储的元素个数,则缩小数组的大小
elementData = Arrays.copyOf( elementData , size );
}
}

/**
* 为了确保数组大小大于minCapacity,也就是数组大小大于需要存储的元素个数,增加数组的大小
* @param    minCapacity   the desired minimum capacity
*/
public void ensureCapacity( int minCapacity ) {
if (minCapacity > 0)
//对数组进行扩容
ensureCapacityInternal( minCapacity );
}

//数组扩容函数
private void ensureCapacityInternal( int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData .length > 0)
grow( minCapacity );
}

/**
* 数组最大容量限制
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

/**
* 增加数组容量函数
* @param minCapacity 渴望数组大小
*/
private void grow(int minCapacity ) {
// overflow-conscious code
int oldCapacity = elementData .length ;
//新数组大小为原数组的1.5倍
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 );
}

//如果新数组大小大于数组最大容量限制
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 ;
}

/**
* 判断是否存储元素
*/
public boolean isEmpty() {
return size == 0;
}

/**
* 集合中是否包含元素o
*/
public boolean contains(Object o ) {
return indexOf(o ) >= 0;
}

/**
* 返回元素在集合中的位置(初次出现的位置)
* 如果集合中不存在该元素,则返回-1,null不能放在equals的左边
*/
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,null不能放在equals的左边
*/
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,并返回
* @return a clone of this <tt> ArrayList </tt> instance
*/
public Object clone() {
try {
@SuppressWarnings ("unchecked" )
ArrayList<E> v = (ArrayList<E>) 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() {
return Arrays.copyOf( elementData , size );
}

/**
* 返回一个指定类型包含全部元素的数组
*/
@SuppressWarnings( "unchecked" )
public <T> T[] toArray(T[] a) {
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);
if (a .length > size )
a[ size] = null ;
return a ;
}

//返回数组指定位置上的元素
E elementData( int index) {
return (E) elementData [index ];
}

/**
* 返回数组指定位置上的元素
*/
public E get( int index ) {
rangeCheck( index);

return elementData(index );
}

/**
* 替换数组指定位置上的元素
*/
public E set( int index , E element ) {
rangeCheck( index);

E oldValue = elementData( index);
elementData [index ] = element ;
return oldValue ;
}

/**
* 在数组的尾部追加一个元素
*/
public boolean add(E e ) {
//先判断数组是否需要扩容
ensureCapacityInternal( size + 1);  // Increments modCount!!
elementData [size ++] = e ;
return true ;
}

/**
* Inserts the specified element at the specified position in this
* list. Shifts the element currently at that position (if any) and
* any subsequent elements to the right (adds one to their indices).
* 在指定位置插入元素
*/
public void add(int index , E element ) {
rangeCheckForAdd( index);
//判断元素是否需要扩容
ensureCapacityInternal( size + 1);  // Increments modCount!!
//System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
//src:源数组;srcPos:源数组要复制的起始位置;dest:目的数组;destPos:目的数组放置的起始位置;length:复制的长度。
//将元素该位置的元素以及之后的数组全部往后移植一位
System. arraycopy( elementData, index, elementData , index + 1,size - index);
elementData [index ] = element ;
size++;
}

/**
* Removes the element at the specified position in this list.
* Shifts any subsequent elements to the left (subtracts one from their
* indices).
* 移除指定位置元素
*/
public E remove( int index ) {
rangeCheck( index);
//修改次数+1
modCount++;
E oldValue = elementData( index);

int numMoved = size - index - 1;
if (numMoved > 0)
System. arraycopy( elementData, index+1, elementData , index , numMoved);
//删除最后一个数组元素的指针,即释放最后一个数组元素指向的对象,让GC能够回收该对象
//关于GC root不熟悉的看下JVM
elementData [--size ] = null; // Let gc do its work
//返回被移除位置的元素
return oldValue ;
}

/**
* 移除集合中的某个元素,如果集合中不存在该元素,则什么都不做
* 返回是否移除成功
*/
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 ;
}

/*
* Private remove method that skips bounds checking and does not
* return the value removed.
* remove(Object o )方法的内部使用方法,私有。
* 此方法相比remove(int index)有何特点?
* 没有进行范围判断,即rangeCheck( 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; // Let gc do its work
}

/**
* 移除所有元素
*/
public void clear() {
modCount++;

// Let gc do its work
for (int i = 0; i < size ; i ++)
elementData [i ] = null;

size = 0;
}

/**
* 追加集合c中的所有元素到ArrayList集合中,存放的先后顺序保持不变。
/
public boolean addAll(Collection<? extends E> c) {
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;

}

/**
* 在执行位置插入集合c中的全部元素
*/
public boolean addAll(int index , Collection<? extends E> c ) {
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;
}

/**
* 移除指定范围内的元素
*/
protected void removeRange( int fromIndex, int toIndex ) {
modCount++;
int numMoved = size - toIndex ;
System. arraycopy( elementData, toIndex, elementData , fromIndex ,
numMoved);

// Let gc do its work
int newSize = size - (toIndex -fromIndex );
while (size != newSize )
elementData [--size ] = null;
}

/**
* 检测指定位置与元素个数大小,如果指定位置大于存储元素个数,则抛出IndexOutOfBoundsException
*/
private void rangeCheck( int index) {
if (index >= size )
throw new IndexOutOfBoundsException(outOfBoundsMsg(index ));
}

/**
* add and addAll操作判断范围的特有方法
*/
private void rangeCheckForAdd( int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index ));
}

/**
* Constructs an IndexOutOfBoundsException detail message.
* Of the many possible refactorings of the error handling code,
* this "outlining" performs best with both server and client VMs.
*/
private String outOfBoundsMsg( int index ) {
return "Index: " +index +", Size: " +size ;
}

/**
* 移除与集合c有交集的元素,使用批量移除方法
*/
public boolean removeAll(Collection<?> c ) {

return batchRemove(c , false);
}

/**
* 保留与集合c有交集的元素,使用批量移除方法
*/
public boolean retainAll(Collection<?> c ) {
return batchRemove(c , true);
}


**下面详细看下批量移除方法:batchRemove。

首先需要明确一点:数组也属于引用数据类型,final Object[] elementData。对于引用类型而言,我们不能改变final修饰的引用的指向,但是我们可以修改指向的具体内容里面的值。就以数组为例:**

public static void main(String[] args) {
final String[] s = {"a" ,"b" ,"c" };
//不能修改指向
// s = new String[5]; The final local variable s cannot be assigned. It must be blank and not using a compound assignment

System.out.println(Arrays.toString(s));

//虽然不能修改指向,但是我们可以修改指向对象中的内容
s[0] = "d";
s[1] = "e";
s[2] = "f";

System.out.println(Arrays.toString(s));

}

输出结果:
[a, b, c]
[d, e, f]


batchRemove定义一个引用指向元素组,然后对原数组中的元素进行操作。

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 {
// 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 ) {
for (int i = w ; i < size ; i ++)
elementData [i ] = null;
modCount += size - w;
size = w;
modified = true ;
}
}
return modified ;
}


public ListIterator<E> listIterator( int index ) {
if (index < 0 || index > size)
throw new IndexOutOfBoundsException( "Index: "+ index);
return new ListItr( index);
}

public ListIterator<E> listIterator() {
return new ListItr(0);
}

public Iterator<E> iterator() {
return new Itr();
}

/**
* 实现Iterator接口的迭代器(内部使用)
*/
private class Itr implements Iterator<E> {
int cursor ;       // 指向当前元素的下一个元素
int lastRet = -1; // 最后一个返回的元素的位置
int expectedModCount = modCount ; //用来判断是否抛出ConcurrentModificationException

//是否还有下一个元素,如果下一个元素的位置小于存储元素数量,返回true,否则false
public boolean hasNext() {
return cursor != size ;
}

//返回下一个元素
@SuppressWarnings ("unchecked" )
public E next() {
//判断是否抛出ConcurrentModificationException(即fast-fail)
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() {
if (lastRet < 0)
throw new IllegalStateException();
//判断是否抛出ConcurrentModificationException(即fast-fail)
checkForComodification();

try {
//移除最后一个返回的元素
ArrayList. this .remove(lastRet );
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount ;
} catch (IndexOutOfBoundsException ex ) {
throw new ConcurrentModificationException();
}
}

//fast-fail具体实现
final void checkForComodification() {
if (modCount != expectedModCount )
throw new ConcurrentModificationException();
}
}

/**
* 实现ListIterator接口的迭代器(内部使用)
*/
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;
}

//返回前一个元素
@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 ) {
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 {
int i = cursor ;
ArrayList. this .add(i , e );
cursor = i + 1;
lastRet = -1;
expectedModCount = modCount ;
} catch (IndexOutOfBoundsException ex ) {
throw new ConcurrentModificationException();
}
}
}

public List<E> subList( int fromIndex , int toIndex) {
subListRangeCheck(fromIndex , toIndex , size );
return new SubList( this, 0, fromIndex , toIndex );
}

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中某段数据的一个视图. 因此, 在操作此方法返回的List时, 同样会改变ArrayList的数据.
//对于结构性修改,通过该类修改,不会导致fast-false;但父ArrayList修改会导致该类的fast-false
private class SubList extends AbstractList<E> implements RandomAccess {
private final AbstractList<E> parent;
private final int parentOffset;
private final int offset;
int size ;

//parent 父类型
//offset 父类型的偏移量
//fromIndex 子列表的开始元素,位于父列表的位置
//toIndex 子列表的结束元素,位于父列表的位置
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;
}

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 = 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 ;
}

public Iterator<E> iterator() {
return listIterator();
}

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;
}

@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<E> 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();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息