赞
踩
import java.util.ArrayList;
import java.util.Iterator;
/**
* @BelongsProject: learn1
* @BelongsPackage: PACKAGE_NAME
* @Author: ZhShy
* @CreateTime: 2022-02-06 11:16
* @Description: arrayList
*/
public class ArrayListDemo {
public static void main(String[] args) {
/**
* 创建一个ArrayList对象,
* 定义元素个数,
* 初始化ArrayList中的元素
*/
ArrayList<Integer> arrayList = new ArrayList<>();
int size = 10;
for (int i = 0; i < size; i++) {
arrayList.add(i);
}
// 调用有参构造传入ArrayList作为参数
ArrayList<Integer> otherList = new ArrayList<>(arrayList);
System.out.println("arrayList的第0个位置元素:" + arrayList.get(0));
System.out.println("arrayList元素5所在位置:" + arrayList.get(5));
System.out.println("arrayList是否包含元素10:" + arrayList.contains(10));
System.out.println("arrayList删除第0个位置元素:" + arrayList.remove(0));
/**
* 获取ArrayList的迭代器
*/
Iterator<Integer> iterator = arrayList.iterator();
while (iterator.hasNext()) {
Integer element = iterator.next();
System.out.println("iterator()迭代器输出ArrayList元素:" + element);
if (element == 5) {
iterator.remove();
System.out.println("iterator()迭代器删除ArrayList元素:" + element);
break;
}
}
iterator.forEachRemaining(integer -> System.out.println("forEachRemaining()输出元素" + integer));
// 删除与ArrayList交集部分
otherList.removeAll(arrayList);
otherList.forEach(integer -> System.out.println("forEach()输出otherList元素:" + integer));
}
}
执行结果:
arrayList的第0个位置元素:0
arrayList元素5所在位置:5
arrayList是否包含元素10:false
arrayList删除第0个位置元素:0
iterator()迭代器输出ArrayList元素:1
iterator()迭代器输出ArrayList元素:2
iterator()迭代器输出ArrayList元素:3
iterator()迭代器输出ArrayList元素:4
iterator()迭代器输出ArrayList元素:5
iterator()迭代器删除ArrayList元素:5
forEachRemaining()输出元素6
forEachRemaining()输出元素7
forEachRemaining()输出元素8
forEachRemaining()输出元素9
forEach()输出otherList元素:0
forEach()输出otherList元素:5
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
ArrayList是顺序表的一种实现,在顺序表的基础上提供了更加丰富的功能。ArrayList继承了AbstractList类,实现了List、RandomAccess、Cloneable、Serializable接口。
/**
* Default initial capacity.
* 默认初始容量。
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* Shared empty array instance used for empty instances.
* 空数组。无参构造器中创建空对象时用到
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
/**
* Shared empty array instance used for default sized empty instances. We
* distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
* first element is added.
* 空数组,用于控制当ArrayList加入新元素时,计算扩充的容量
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* will be expanded to DEFAULT_CAPACITY when the first element is added.
* ArrayList存放元素的数组
*/
transient Object[] elementData; // non-private to simplify nested class access
/**
* The size of the ArrayList (the number of elements it contains).
*
* @serial
* ArrayList包含的元素个数
*/
private int size;
ArrayList类是基于数组实现的线性表,并且用size属性记录ArrayList对象中包含的元素的个数,因此获取ArrayList对象的大小的时间复杂度为O(1),因为不需要对ArrayList对象中的每个元素进行遍历。
/**
* 构造一个具有指定初始容量的空列表
* Constructs an empty list with the specified initial capacity.
*
* @param initialCapacity the initial capacity of the list
* @throws IllegalArgumentException if the specified initial capacity is negative
*/
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);
}
}
带初始容量的构造器中会对指定的初始容量进行校验。如果初始容量参数非法,就会抛出IllegalArgumentException异常。初始容量不宜设置过大,否则可能会造成存储空间浪费,甚至会影响JVM(Java Virtual Machine,Java虚拟机)的性能。
/**
* Constructs an empty list with an initial capacity of ten.
* 无参构造器
*/
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.
*
* @param c the collection whose elements are to be placed into this list
* @throws NullPointerException if the specified collection is null
* 带集合参数的构造器
*/
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// defend against c.toArray (incorrectly) not returning Object[]
// (see e.g. https://bugs.openjdk.java.net/browse/JDK-6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
ArrayList添加元素的方法有两个重载的方法,分别是add(E e)
和add(int index,E element)
。
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return {@code true} (as specified by {@link Collection#add})
*/
public boolean add(E e) {
modCount++;
add(e, elementData, size);
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).
*
* @param index index at which the specified element is to be inserted
* @param element element to be inserted
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public void add(int index, E element) {
rangeCheckForAdd(index);
modCount++;
final int s;
Object[] elementData;
if ((s = size) == (elementData = this.elementData).length)
elementData = grow();
System.arraycopy(elementData, index,
elementData, index + 1,
s - index);
elementData[index] = element;
size = s + 1;
}
以 add(E e)
为例,
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return {@code true} (as specified by {@link Collection#add})
*/
public boolean add(E e) {
modCount++;
add(e, elementData, size);
return true;
}
这段代码使用到了一个modCount
变量和add()
函数
其中的add()
函数:
/**
* This helper method split out from add(E) to keep method
* bytecode size under 35 (the -XX:MaxInlineSize default value),
* which helps when add(E) is called in a C1-compiled loop.
*/
private void add(E e, Object[] elementData, int s) {
if (s == elementData.length)
elementData = grow();
elementData[s] = e;
size = s + 1;
}
这段代码可以看出,先判断当前容量是否足够再插入一个元素,如果不够则调用grow()
函数,然后再将相应位置插入元素,同时size增加1.
grow()
函数:
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
* @throws OutOfMemoryError if minCapacity is less than zero
*/
private Object[] grow(int minCapacity) {
return elementData = Arrays.copyOf(elementData, newCapacity(minCapacity));
}
private Object[] grow() {
return grow(size + 1);
}
grow()
方法的大致意思是将数组复制到另一个更大的数组里,其中调用了newCapacity()
方法:
/**
* Returns a capacity at least as large as the given minimum capacity.
* Returns the current capacity increased by 50% if that suffices.
* Will not return a capacity greater than MAX_ARRAY_SIZE unless
* the given minimum capacity is greater than MAX_ARRAY_SIZE.
*
* @param minCapacity the desired minimum capacity
* @throws OutOfMemoryError if minCapacity is less than zero
*/
private int newCapacity(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
// 新数组为旧数组容积的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 如果仍然不够则给它一个足够大的容积
if (newCapacity - minCapacity <= 0) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
return Math.max(DEFAULT_CAPACITY, minCapacity);
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return minCapacity;
}
return (newCapacity - MAX_ARRAY_SIZE <= 0)
? newCapacity
: hugeCapacity(minCapacity);
}
代码末尾调用了一个hugeCapacity()
函数:
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE)
? Integer.MAX_VALUE
: MAX_ARRAY_SIZE;
}
如果最小容量minCapacity
小于0,就说明int类型的minCapacity
发生了溢出,抛出OutOfMemoryError
错误。如果最小容量minCapacity
大于MAX_ARRAY_SIZE
,就返回Integer.MAX_VALUE
。由此可知,ArrayList的最大容量是Integer.MAX_VALUE
。
而add(int index, E element)
只是比add(E e)
方法多了两个方法调用,其余的处理逻辑与add(E e)
方法类似。
/**
* 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).
*
* @param index index at which the specified element is to be inserted
* @param element element to be inserted
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public void add(int index, E element) {
rangeCheckForAdd(index);
modCount++;
final int s;
Object[] elementData;
if ((s = size) == (elementData = this.elementData).length)
elementData = grow();
System.arraycopy(elementData, index,
elementData, index + 1,
s - index);
elementData[index] = element;
size = s + 1;
}
add(int index, E element)
首先需要通过rangeCheckForAdd()
方法校验插入新元素的位置是否合法:
/**
* A version of rangeCheck used by add and addAll.
*/
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
add(int index, E element)
还调用System.arraycopy()
方法进行数组拷贝,将数组的第index位置空出,用于存储新元素。
ArrayList查询元素的方法主要分为两类:一类是已知位置信息,查询ArrayList中的元素;另一类是已知元素信息,查询ArrayList中的位置信息或者ArrayList是否包含指定元素。
get()方法是通过指定位置信息查询ArrayList指定位置的元素
/**
* Returns the element at the specified position in this list.
*
* @param index index of the element to return
* @return the element at the specified position in this list
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E get(int index) {
Objects.checkIndex(index, size);
return elementData(index);
}
get()
函数首先用Objects.checkIndex()
对index判断位置是否合法,然后调用elementData()
方法。
E elementData(int index) {
return (E) elementData[index];
}
indexOf()方法是通过指定的元素查询元素在ArrayList第1次出现的位置。
/**
* Returns the index of the first occurrence of the specified element
* in this list, or -1 if this list does not contain the element.
* More formally, returns the lowest index {@code i} such that
* {@code Objects.equals(o, get(i))},
* or -1 if there is no such index.
*/
public int indexOf(Object o) {
return indexOfRange(o, 0, size);
}
int indexOfRange(Object o, int start, int end) {
Object[] es = elementData;
if (o == null) {
for (int i = start; i < end; i++) {
if (es[i] == null) {
return i;
}
}
} else {
for (int i = start; i < end; i++) {
if (o.equals(es[i])) {
return i;
}
}
}
return -1;
}
从indexOf()方法的源码可知,此方法只能找到ArrayList中第1次出现指定元素的位置,找到后立即返回。indexOf()方法比较元素相等用的是equals()方法,因此两个equals()相等的元素被ArrayList认为是同一个元素。
lastIndexOf()方法是通过指定的元素查询元素在ArrayList最后一次出现的位置。lastIndexOf()方法代码如下:
/**
* Returns the index of the last occurrence of the specified element
* in this list, or -1 if this list does not contain the element.
* More formally, returns the highest index {@code i} such that
* {@code Objects.equals(o, get(i))},
* or -1 if there is no such index.
*/
public int lastIndexOf(Object o) {
return lastIndexOfRange(o, 0, size);
}
int lastIndexOfRange(Object o, int start, int end) {
Object[] es = elementData;
if (o == null) {
for (int i = end - 1; i >= start; i--) {
if (es[i] == null) {
return i;
}
}
} else {
for (int i = end - 1; i >= start; i--) {
if (o.equals(es[i])) {
return i;
}
}
}
return -1;
}
lastIndexOf()方法与indexOf()方法的不同之处仅仅在于,lastIndexOf()方法从ArrayList最后一个元素的位置向前搜索,返回指定元素最后一次出现的位置。
contains()方法返回boolean值,用于检查指定的元素是否存在于ArrayList中。contains()方法代码如下:
/**
* Returns {@code true} if this list contains the specified element.
* More formally, returns {@code true} if and only if this list contains
* at least one element {@code e} such that
* {@code Objects.equals(o, e)}.
*
* @param o element whose presence in this list is to be tested
* @return {@code true} if this list contains the specified element
*/
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
从contains()方法的代码可知,contains()借助indexOf()方法实现功能。如果指定的元素存在于ArrayList中,indexOf()就会返回元素的位置信息,其位置信息一定是大于等于0的一个数,此时contains()方法返回true;否则indexOf()方法将返回-1,此时contains()方法返回false。
set()方法用指定的元素替换此ArrayList中指定位置的元素
/**
* Replaces the element at the specified position in this list with
* the specified element.
*
* @param index index of the element to replace
* @param element element to be stored at the specified position
* @return the element previously at the specified position
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E set(int index, E element) {
Objects.checkIndex(index, size);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
remove(int index)方法是删除指定位置index上的元素。如果删除的位置不合法,就会抛出IndexOutOfBoundsException异常。如果删除的并非是最后一个位置的元素,就会通过System.arraycopy()方法将index以后的元素依次向前移动。最后返回删除的元素。
/**
* Removes the element at the specified position in this list.
* Shifts any subsequent elements to the left (subtracts one from their
* indices).
*
* @param index the index of the element to be removed
* @return the element that was removed from the list
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E remove(int index) {
Objects.checkIndex(index, size);
final Object[] es = elementData;
@SuppressWarnings("unchecked") E oldValue = (E) es[index];
fastRemove(es, index);
return oldValue;
}
/**
* Private remove method that skips bounds checking and does not
* return the value removed.
*/
private void fastRemove(Object[] es, int i) {
modCount++;
final int newSize;
if ((newSize = size - 1) > i)
System.arraycopy(es, i + 1, es, i, newSize - i);
es[size = newSize] = null;
}
与remove(int index)方法不同的是,remove(Object o)方法不是删除指定位置的元素,而是删除ArrayList中与指定元素相等的元素。与indexOf()方法和lastIndexOf()方法类似,remove(int index)方法判断元素是否相等也是通过equals()方法。remove(Object o)方法删除元素通过fastRemove()方法实现。
/**
* Removes the first occurrence of the specified element from this list,
* if it is present. If the list does not contain the element, it is
* unchanged. More formally, removes the element with the lowest index
* {@code i} such that
* {@code Objects.equals(o, get(i))}
* (if such an element exists). Returns {@code true} if this list
* contained the specified element (or equivalently, if this list
* changed as a result of the call).
*
* @param o element to be removed from this list, if present
* @return {@code true} if this list contained the specified element
*/
public boolean remove(Object o) {
final Object[] es = elementData;
final int size = this.size;
int i = 0;
found: {
if (o == null) {
for (; i < size; i++)
if (es[i] == null)
break found;
} else {
for (; i < size; i++)
if (o.equals(es[i]))
break found;
}
return false;
}
fastRemove(es, i);
return true;
}
sort():
@Override
@SuppressWarnings("unchecked")
public void sort(Comparator<? super E> c) {
final int expectedModCount = modCount;
Arrays.sort((E[]) elementData, 0, size, c);
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
modCount++;
}
sort()方法根据传入的比较器Comparator调用Arrays.sort()方法进行排序。这里也是策略设计模式的一种运用场景。Comparator是一个函数式接口,JDK1.8对Comparator接口做了修改,在其中加入了很多默认方法,此处只节选了compare()方法,因为compare()方法是Arrays.sort()方法中用到的。Arrays.sort()方法代码如下:
public static <T> void sort(T[] a, int fromIndex, int toIndex,
Comparator<? super T> c) {
if (c == null) {
sort(a, fromIndex, toIndex);
} else {
rangeCheck(a.length, fromIndex, toIndex);
if (LegacyMergeSort.userRequested)
legacyMergeSort(a, fromIndex, toIndex, c);
else
TimSort.sort(a, fromIndex, toIndex, c, null, 0, 0);
}
}
Arrays.sort()方法会使用ComparableTimSort.sort()方法或者TimSort.sort()方法进行排序。这两种排序方法的实现方式类似,不同之处在于,TimSort.sort()使用自定义比较器进行排序,ComparableTimSort.sort()使用元素的自然顺序进行排序。所谓的自然顺序,即实现了Comparable接口的类,如Integer类或者String类等,这些类的对象可以直接进行大小比较,因为没有自定义的比较器也可以对其进行排序。此处使用的TimSort排序算法是一种混合、稳定高效的排序算法。TimSort排序算法是由Tim Peters于2002年实施使用在Python编程语言中的。从2.3版本开始,TimSort一直是Python的标准排序算法。Java中也实现了TimSort算法。
/**
* Returns an iterator over the elements in this list in proper sequence.
*
* <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
*
* @return an iterator over the elements in this list in proper sequence
*/
public Iterator<E> iterator() {
return new Itr();
}
从iterator()方法的代码可知,iterator()方法将返回一个内部类Itr对象。
/**
* An iterator over a collection. {@code Iterator} takes the place of
* {@link Enumeration} in the Java Collections Framework. Iterators
* differ from enumerations in two ways:
*
* <ul>
* <li> Iterators allow the caller to remove elements from the
* underlying collection during the iteration with well-defined
* semantics.
* <li> Method names have been improved.
* </ul>
*
* <p>This interface is a member of the
* <a href="{@docRoot}/java.base/java/util/package-summary.html#CollectionsFramework">
* Java Collections Framework</a>.
*
* @apiNote
* An {@link Enumeration} can be converted into an {@code Iterator} by
* using the {@link Enumeration#asIterator} method.
*
* @param <E> the type of elements returned by this iterator
*
* @author Josh Bloch
* @see Collection
* @see ListIterator
* @see Iterable
* @since 1.2
*/
public interface Iterator<E> {
/**
* Returns {@code true} if the iteration has more elements.
* (In other words, returns {@code true} if {@link #next} would
* return an element rather than throwing an exception.)
*
* @return {@code true} if the iteration has more elements
*/
boolean hasNext();
/**
* Returns the next element in the iteration.
*
* @return the next element in the iteration
* @throws NoSuchElementException if the iteration has no more elements
*/
E next();
/**
* Removes from the underlying collection the last element returned
* by this iterator (optional operation). This method can be called
* only once per call to {@link #next}.
* <p>
* The behavior of an iterator is unspecified if the underlying collection
* is modified while the iteration is in progress in any way other than by
* calling this method, unless an overriding class has specified a
* concurrent modification policy.
* <p>
* The behavior of an iterator is unspecified if this method is called
* after a call to the {@link #forEachRemaining forEachRemaining} method.
*
* @implSpec
* The default implementation throws an instance of
* {@link UnsupportedOperationException} and performs no other action.
*
* @throws UnsupportedOperationException if the {@code remove}
* operation is not supported by this iterator
*
* @throws IllegalStateException if the {@code next} method has not
* yet been called, or the {@code remove} method has already
* been called after the last call to the {@code next}
* method
*/
default void remove() {
throw new UnsupportedOperationException("remove");
}
/**
* Performs the given action for each remaining element until all elements
* have been processed or the action throws an exception. Actions are
* performed in the order of iteration, if that order is specified.
* Exceptions thrown by the action are relayed to the caller.
* <p>
* The behavior of an iterator is unspecified if the action modifies the
* collection in any way (even by calling the {@link #remove remove} method
* or other mutator methods of {@code Iterator} subtypes),
* unless an overriding class has specified a concurrent modification policy.
* <p>
* Subsequent behavior of an iterator is unspecified if the action throws an
* exception.
*
* @implSpec
* <p>The default implementation behaves as if:
* <pre>{@code
* while (hasNext())
* action.accept(next());
* }</pre>
*
* @param action The action to be performed for each element
* @throws NullPointerException if the specified action is null
* @since 1.8
*/
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
}
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;
}
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];
}
next()方法调用checkForComodification()方法用于检测迭代器执行过程中是否有并发修改,如果有并发修改,就会抛出ConcurrentModificationException异常。此异常的作用通常是阻止并发修改ArrayList对象。例如,当一个线程通过迭代器修改一个ArrayList时,另一个线程修改ArrayList是不允许的。迭代器通过ConcurrentModificationException异常阻止这种情况的发生,这种迭代器也称作fast-fail迭代器。
3. Itr类实现remove()方法用于删除此迭代器返回的最后一个元素
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
@Override
public void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
final int size = ArrayList.this.size;
int i = cursor;
if (i < size) {
final Object[] es = elementData;
if (i >= es.length)
throw new ConcurrentModificationException();
for (; i < size && modCount == expectedModCount; i++)
action.accept(elementAt(es, i));
// update once at end to reduce heap write traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}
}
/**
* An iterator for lists that allows the programmer
* to traverse the list in either direction, modify
* the list during iteration, and obtain the iterator's
* current position in the list. A {@code ListIterator}
* has no current element; its <I>cursor position</I> always
* lies between the element that would be returned by a call
* to {@code previous()} and the element that would be
* returned by a call to {@code next()}.
* An iterator for a list of length {@code n} has {@code n+1} possible
* cursor positions, as illustrated by the carets ({@code ^}) below:
* <PRE>
* Element(0) Element(1) Element(2) ... Element(n-1)
* cursor positions: ^ ^ ^ ^ ^
* </PRE>
* Note that the {@link #remove} and {@link #set(Object)} methods are
* <i>not</i> defined in terms of the cursor position; they are defined to
* operate on the last element returned by a call to {@link #next} or
* {@link #previous()}.
*
* <p>This interface is a member of the
* <a href="{@docRoot}/java.base/java/util/package-summary.html#CollectionsFramework">
* Java Collections Framework</a>.
*
* @author Josh Bloch
* @see Collection
* @see List
* @see Iterator
* @see Enumeration
* @see List#listIterator()
* @since 1.2
*/
public interface ListIterator<E> extends Iterator<E> {
// Query Operations
/**
* Returns {@code true} if this list iterator has more elements when
* traversing the list in the forward direction. (In other words,
* returns {@code true} if {@link #next} would return an element rather
* than throwing an exception.)
*
* @return {@code true} if the list iterator has more elements when
* traversing the list in the forward direction
*/
boolean hasNext();
/**
* Returns the next element in the list and advances the cursor position.
* This method may be called repeatedly to iterate through the list,
* or intermixed with calls to {@link #previous} to go back and forth.
* (Note that alternating calls to {@code next} and {@code previous}
* will return the same element repeatedly.)
*
* @return the next element in the list
* @throws NoSuchElementException if the iteration has no next element
*/
E next();
/**
* Returns {@code true} if this list iterator has more elements when
* traversing the list in the reverse direction. (In other words,
* returns {@code true} if {@link #previous} would return an element
* rather than throwing an exception.)
*
* @return {@code true} if the list iterator has more elements when
* traversing the list in the reverse direction
*/
boolean hasPrevious();
/**
* Returns the previous element in the list and moves the cursor
* position backwards. This method may be called repeatedly to
* iterate through the list backwards, or intermixed with calls to
* {@link #next} to go back and forth. (Note that alternating calls
* to {@code next} and {@code previous} will return the same
* element repeatedly.)
*
* @return the previous element in the list
* @throws NoSuchElementException if the iteration has no previous
* element
*/
E previous();
/**
* Returns the index of the element that would be returned by a
* subsequent call to {@link #next}. (Returns list size if the list
* iterator is at the end of the list.)
*
* @return the index of the element that would be returned by a
* subsequent call to {@code next}, or list size if the list
* iterator is at the end of the list
*/
int nextIndex();
/**
* Returns the index of the element that would be returned by a
* subsequent call to {@link #previous}. (Returns -1 if the list
* iterator is at the beginning of the list.)
*
* @return the index of the element that would be returned by a
* subsequent call to {@code previous}, or -1 if the list
* iterator is at the beginning of the list
*/
int previousIndex();
// Modification Operations
/**
* Removes from the list the last element that was returned by {@link
* #next} or {@link #previous} (optional operation). This call can
* only be made once per call to {@code next} or {@code previous}.
* It can be made only if {@link #add} has not been
* called after the last call to {@code next} or {@code previous}.
*
* @throws UnsupportedOperationException if the {@code remove}
* operation is not supported by this list iterator
* @throws IllegalStateException if neither {@code next} nor
* {@code previous} have been called, or {@code remove} or
* {@code add} have been called after the last call to
* {@code next} or {@code previous}
*/
void remove();
/**
* Replaces the last element returned by {@link #next} or
* {@link #previous} with the specified element (optional operation).
* This call can be made only if neither {@link #remove} nor {@link
* #add} have been called after the last call to {@code next} or
* {@code previous}.
*
* @param e the element with which to replace the last element returned by
* {@code next} or {@code previous}
* @throws UnsupportedOperationException if the {@code set} operation
* is not supported by this list iterator
* @throws ClassCastException if the class of the specified element
* prevents it from being added to this list
* @throws IllegalArgumentException if some aspect of the specified
* element prevents it from being added to this list
* @throws IllegalStateException if neither {@code next} nor
* {@code previous} have been called, or {@code remove} or
* {@code add} have been called after the last call to
* {@code next} or {@code previous}
*/
void set(E e);
/**
* Inserts the specified element into the list (optional operation).
* The element is inserted immediately before the element that
* would be returned by {@link #next}, if any, and after the element
* that would be returned by {@link #previous}, if any. (If the
* list contains no elements, the new element becomes the sole element
* on the list.) The new element is inserted before the implicit
* cursor: a subsequent call to {@code next} would be unaffected, and a
* subsequent call to {@code previous} would return the new element.
* (This call increases by one the value that would be returned by a
* call to {@code nextIndex} or {@code previousIndex}.)
*
* @param e the element to insert
* @throws UnsupportedOperationException if the {@code add} method is
* not supported by this list iterator
* @throws ClassCastException if the class of the specified element
* prevents it from being added to this list
* @throws IllegalArgumentException if some aspect of this element
* prevents it from being added to this list
*/
void add(E e);
}
public boolean hasPrevious() {
return cursor != 0;
}
public int nextIndex() {
return cursor;
}
public int previousIndex() {
return cursor - 1;
}
public E previous() {
checkForComodification();
int i = cursor - 1;
if (i < 0)
throw new NoSuchElementException();
Object[] elementData = root.elementData;
if (offset + i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i;
return (E) elementData[offset + (lastRet = i)];
}
public void set(E e) {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
root.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 = root.modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。