用java源代码学数据结构<四>: LinkedList 详解(五)
//保存next的节点信息,
lastReturned = next;
next = next.next;
nextIndex++;
return lastReturned.item;
}
public boolean hasPrevious() {
return nextIndex > 0;
}
//同next
public E previous() {
checkForComodification();
if (!hasPrevious())
throw new NoSuchElementException();
lastReturned = next = (next == null) last : next.prev;
nextIndex--;
return lastReturned.item;
}
public int nextIndex() {
return nextIndex;
}
public int previousIndex() {
return nextIndex - 1;
}
public void remove() {
checkForComodification();
//必须先调用itr.next或itr.previous之后才能调用remove和set
if (lastReturned == null)
throw new IllegalStateException();
Node lastNext = lastReturned.next;
//unlink将lastReturned设置为null,同时将lastReturned前后节点连在一起
unlink(lastReturned);
/*
调用itr.next()后,lastReturned位于next的前面一个
调用itr.previous()后,lastReturned与next在同一位置
*/
if (next == lastReturned)
/*1.在previous()中有这样一句
lastReturned = next = (next == null) last : next.prev;
最后return lastReturned.item;
2.如果调用的是itr.previous,则下一次previous要求返回这次previous之前
的那个元素,而此时next和lastReturned都为null,但unlink将lastReturned
的前后节点连在了一起,我们就需要将next设置为当前lastReturned的后面
一个节点,即next = lastNext;
*/
next = lastNext;
//3.因为是向前访问,而删除的元素在next的后面,所以不修改nextIndex
else
/*
同理,如果调用的是next(),则lastReturned在next的前面一个位置,
删除了lastReturned所指的对象,没必修改next了
*/
nextIndex--;//删除的元素在next的前面
lastReturned = null;
expectedModCount++;
}
public void set(E e) {
if (lastReturned == null)
throw new IllegalStateException();
checkForComodification();
lastReturned.item = e;
}
public void add(E e) {
checkForComodification();
lastReturned = null;
if (next == null)
linkLast(e);
else
linkBefore(e, next);
nextIndex++;
expectedModCount++;
}
//检查线程同步
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
//返回反向迭代器
public Iterator descendingIterator() {
return new DescendingIterator();
}
private class DescendingIterator implements Iterator {
private final ListItr itr = new ListItr(size());
//将正向迭代器方法反着用
public boolean hasNext() {
return itr.hasPrevious();
}
public E next() {
return itr.previous();
}
public void remove() {
itr.remove();
}
}
@SuppressWarnings("unchecked")
private LinkedList superClone() {
try {
return (LinkedList) super.clone(