您的位置:首页 > 编程语言 > Java开发

Java集合(3)——ListIterator接口源码 & ListIterator接口与Iterator接口辨析

2018-02-08 17:47 567 查看

ListIterator接口



官方文档描述:

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 ListIterator has no current element; its cursor position always lies between the element that would be returned by a call to
previous()
and the element that would be returned by a call to
next().
An iterator for a list of length n has n+1 possible cursor positions, as illustrated by the carets (^) below:



翻译: 允许开发人员遍历任意方向的集合的迭代器,可以在迭代过程中修改列表,也可以获取迭代器当前位置。一个ListIterator没有当前的元素,它的cursor位置总是在两个元素之间。这两个元素可以一个被
previous()
方法返回,一个被
next()
返回。长度为n的集合有n+1个可能的cursor位置。

ListIterator接口中的成员方法



package java.util;

public interface ListIterator<E> extends Iterator<E> {
// Query Operations
boolean hasNext();

E next();

boolean hasPrevious();

E previous();

int nextIndex();

int previousIndex();

// Modification Operations

void remove();

void set(E e);

void add(E e);
}


ListIterator是一个更加强大的Iterator子接口,它只能用于各种List接口的子类访问。因为ListIterator没有实现类,只有List接口中有一个返回值类型为ListIterator的
listIterator()
方法。而AbstractList作为List的直接子类,实现了
listIterator()
方法。

在AbstractList中实现Iterator接口使用了一个方法,一个内部类。实现ListIterator接口使用了两个方法,两个内部类。

AbstractList抽象类中实现Iterator接口源码解析

使用了一个
Public Iterator<E> iterator()
方法和
private class Itr implements Iterator<E>


Public Iterator<E> iterator()
方法源码

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


可以看出在这个方法中只是创建了Itr类的对象,所以主要的实现过程还要看Itr类。

private class Itr implements Iterator<E>
类源码

该类包含3个成员变量,4个需要实现Ietrator接口的方法。(该部分涉及到fail-fast机制,也叫ConcurrentModificationException异常)

protected transient int modCount = 0;
private class Itr implements Iterator<E> {

int cursor = 0;    //游标位置,初始设置为0
int lastRet = -1;  //当前游标位置的前一个位置,初始设置为-1
int expectedModCount = modCount;  //游标中的ModCount值,如果与集合中的ModCount值不同就会抛出异常!

public boolean hasNext() {
return cursor != size();
}

public E next() {
checkForComodification();
try {
int i = cursor;
E next = get(i);
lastRet = i;
cursor = i + 1;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}

public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();

try {
AbstractList.this.remove(lastRet);
if (lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}

final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}


AbstractList抽象类中实现ListIterator接口源码解析

实现该方法有两种方式,一种是无参数的,一种是有参数的

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

public ListIterator<E> listIterator(final int index) {
rangeCheckForAdd(index);

return new ListItr(index);
}


从上述源码中可以看出,无参数的
listIterator()
方法调用的是有参数的
listIterator(fianl int index)
方法,只不过将参数值设置为0。有参数的方法先判断Index值是否符合范围,如果符合范围,就调用内部类
ListItr


private class ListItr extends Itr implements ListIterator<E>
类源码

private class ListItr extends Itr implements ListIterator<E> {
ListItr(int index) {
cursor = index;
}

public boolean hasPrevious() {
return cursor != 0;
}

public E previous() { //注意:向前操作也是两步,第一步是得到游标的前一个元素,第二步是将游标的当前位置赋值给游标的下一个位置
checkForComodification();
try {
int i = cursor - 1;
E previous = get(i);
lastRet = cursor = i;
return previous;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}

public int nextIndex() {
return cursor;
}

public int previousIndex() {
return cursor-1;
}

public void set(E e) {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();

try {
AbstractList.this.set(lastRet, e);//这个`set()`方法在抽象类中没有具体实现,方法体只是抛出了异常,具体操作需要子类自己实现

expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}

public void add(E e) {
checkForComodification();

try {
int i = cursor;
AbstractList.this.add(i, e);  //这个`add()`方法在抽象类中没有具体实现,方法体只是抛出了异常,具体操作需要子类自己实现
lastRet = -1;
cursor = i + 1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
}


可以看出该类继承了刚刚的内部类Itr,然后实现了ListIterator接口,实现了接口中的方法。

Iterator接口和ListIterator接口的主要区别

ListIterator有
add()
方法,可以向List中添加对象,而Iterator不能添加对象

Iterator只能向前遍历,但是ListIterator可以双向移动,它还可以产生相对于迭代器在列表中指向的前一个和后一个元素的位置索引。最主要的是ListIterator可以反向迭代List

ListIterator可以使用
set()
方法替换他访问过的最后一个元素。但是Iterator只能遍历集合,不能修改集合。

感谢

http://blog.csdn.net/u011240877/article/details/52752589

http://blog.csdn.net/a597926661/article/details/7679765

https://docs.oracle.com/javase/8/docs/api/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: