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()方法同理.