1.介紹
listiterator 是一個強大的iterator子類型,能用于各種list類的通路.比如 雙向移動,修改指定下表的值. 比lierator多了很多功能,算是iterator一個加強版本.
2.使用
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
ListIterator<Integer> it = list.listIterator();
while (it.hasNext()) {
System.out.println(it.next()); // 1 2 3
}
while (it.hasPrevious()) {
System.out.println(it.previous()); // 3 2 1
}
it = list.listIterator(1);
it.next();// 要先next 才能設定
it.set(5);
System.out.println(list); // [1, 5, 3]
可以看到,listIterator 可以通過 previous() 方法 從後往前周遊,自由控制周遊的方向.
還可以通過 listIterator(int index) 擷取指定下表開始的疊代器,并通過 set 方法 修改 .
這裡有個注意事項: 在set方法執行前需要先執行 next 方法, 為什麼要這樣做, 需要分析下源碼
private class Itr implements Iterator<E> {
int cursor; // 下一個要傳回的元素
int lastRet = -1; // 上一個要傳回的元素,-1代表沒有
int expectedModCount = modCount;
Itr() {}
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
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]; // 這裡 lastRet 指派為 0
}
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();
}
}
public void set(E e) {
if (lastRet < 0) // lastRet如果為 -1 則抛出異常
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.set(lastRet, e);
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
可以看到 lastRet 這個參數預設是 -1, 而 set() 方法在最開始檢測了這個變量,是以需要 在 next() 方法中把 last Ret指派後才不會為 -1, next() return 方法可見 cursor 最後指派給了 lastRet;
remove()方法同理.