在看listIterator迭代器之前,我们先来总结一下它与iterator迭代器的相同点和不同点。
相同点:
1)都是迭代器,在对集合进行遍历时都可以使用。
2)都有hashNext和next方法,都能顺序遍历。
3)都可以实现删除操作。
说的更直白一点的话,就是iterator有的方法功能,listIterator都包含了,因为它会继承iterator在list的实现类。
那我们就看一下listIterator到底与iterator有什么不同吧。
不同点:
1)listIterator只能用于list集合,而不能用于所有的集合。
2)listIterator可以实现向list中添加元素。
4)listIterator可以实现list修改元素。
5)listIterator可以实现逆序遍历。
6)listIterator可以定位当前索引位置。
那么listIterator多了那些方法?看一下源码:
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];
}
这个previous()方法与next()方法相反,它是返回迭代位置之前的元素,那么对应的肯定有一个类似于HashNext()的方法:
public boolean hasPrevious() {
return cursor != 0;
}
这个方法就是判断当前指针位置有没有超过第一个指针位置,没有就返回true,有的话就返回false。
这里的cursor是下一个元素的索引,在previous()方法中,i表示的那就是当前的索引,然后重新将值赋给了cursor,取值的时候则是根据i取得当前的元素。这样就实现了逆序遍历的过程。这个过程正好与顺序遍历相反,顺序遍历哪里的cursor = i + 1;
逆序遍历需要先获取最后的指针,就是列表的结尾,写个测试小例子:
public static void main(String[] args) throws CloneNotSupportedException {
ArrayList a=new ArrayList<>();
a.add("1");
a.add("2");
a.add("3");
a.add("4");
ListIterator b = a.listIterator();
while(b.hasNext()) {
System.out.println("顺序遍历:"+b.next());
}
for(;b.hasPrevious();) {
System.out.println("逆序遍历:"+b.previous());
}
}
打印结果:
顺序遍历:1
顺序遍历:2
顺序遍历:3
顺序遍历:4
逆序遍历:4
逆序遍历:3
逆序遍历:2
逆序遍历:1
实现了我们想要的打印结果。
接下来我们来看看它的添加方法:
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();
}
}
首先它校验了int expectedModCount = modCount;是否是一致的,这就是看看在迭代过程中有没有调用ArrayList中的操作。
然后调用ArrayList的add方法,这里的的方法使得modCount数值加1,这样在最后又进行了一次赋值expectedModCount = modCount;使得在迭代过程中执行此操作时也保持expectedModCount 的数值与modCount相等。cursor = i + 1;是下一个索引数,而首次添加则根据迭代的顺序进行,这里的添加是看cursor 的值进行的如果为0的话就在开头添加。
还有一个特有方法set方法:
public void set(E e) {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.set(lastRet, e);
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
从方法中可以看到,ListIterator迭代器中的set传的参数只有元素,没有传指针,而在下面它获取了list中的最后一个指针,调用ArrayList方法中的set(key,value)说明迭代器中的set添加元素是放在list后面的。