赞
踩
目录
1,迭代器循环
2,增强for循环
3,普通for循环
迭代器创建后,最好立即使用,不然之后对集合进行的增删改操作会导致迭代器遍历报错
原因:
1,系统创建迭代器时,会初始化 字段 expectedModCount = modCount,迭代器遍历获取字段时,next()会先对该字段进行校验
2, 对集合进行的 任何增删 操作都会导致 modCount++,从而在迭代器遍历时,在expectedModCount == modCount 中返回false,导致报错
- private class Itr implements Iterator<E> {
- int cursor; // index of next element to return
- int lastRet = -1; // index of last element returned; -1 if no such
- int expectedModCount = modCount; //初始化 expectedModCount 字段
-
- public E next() {
- //获取下个元素时 , 会先对字段 expectedModCount == modCount 进行校验
- checkForComodification();
- ....
- }
-
- final void checkForComodification() {
- if (modCount != expectedModCount) // 不相等,会报错
- throw new ConcurrentModificationException();
- }
- }

1,单向遍历
2,遍历过程中,不能增加和修改元素
3,遍历过程中,只能使用 Iterator提供的remove() 删除元素,不能使用Collection.remove() 删除元素
删除元素前,需要先调用next(),否则会报错
因为remove()中,更新 lastRet=-1,而要调用remove(),会先校验lastRet<0,抛异常
范例:
- Collection<Student> c = new ArrayList<Student>();
- Student s1 = new Student("zhang", 12);
- Student s2 = new Student("lsii", 23);
- Student s3 = new Student("wangwu", 24);
- Student s4 = new Student("zhoaliu", 24);
-
- c.add(s1);
- c.add(s2);
- c.add(s3);
- c.add(s4);
-
- Iterator<Student> itStu = c.iterator();
- while (itStu.hasNext()) {
- Student s = itStu.next();
- if (s.getName() == "lisi") {
- // c.remove(s1); 会报错
- itStu.remove(); //删除遍历得到的元素
- }
- System.out.println(s);
- }
- System.out.println(c);

hasNext() 是否还有下一个元素:通过cursor字段,判断是否到达集合边界
next() 先让游标后移一位,再返回索引元素
remove() 删除元素
- public E next() {
- checkForComodification();
- int i = cursor;
- ...
- Object[] elementData = ArrayList.this.elementData;
- ...
- cursor = i + 1;
- return (E) elementData[lastRet = i];
- }
-
- //不能直接调用,remove前需要调用next(),因为本方法中 lastRet字段
- public void remove() {
- if (lastRet < 0)
- throw new IllegalStateException();
- checkForComodification();
-
- try {
- ArrayList.this.remove(lastRet);
- cursor = lastRet;
- lastRet = -1; //更新 lastRet
- expectedModCount = modCount; //执行完 remove后,更新 expectedModCount
- } catch (IndexOutOfBoundsException ex) {
- throw new ConcurrentModificationException();
- }
- }

描述: 弥补了Iterator迭代过程中,不能增加元素
1,双向遍历
2,遍历过程中,可以使用迭代器方法,增删改集合元素
1,删除元素前,必须调用next(),否则会报错
因为remove()中,更新 lastRet=-1,而要调用remove(),会先校验lastRet<0,抛异常
2,下面代码中,如果没有调用next(),只是单纯的add(), 会导致死循环,直到内存溢出,引发错误
解决方案:
add() 和 next() 一起使用
范例:
- ArrayList<Student> c = new ArrayList<Student>();
- Student s1 = new Student("zhang", 12);
- Student s2 = new Student("lsii", 23);
- Student s3 = new Student("wangwu", 24);
- Student s4 = new Student("zhoaliu", 24);
-
- c.add(s1);
- c.add(s2);
- c.add(s3);
- c.add(s4);
-
- ListIterator<Student> listIterator = c.listIterator();
- while(listIterator.hasNext()){
- listIterator.add(s3);
- // listIterator.remove(); //直接删除会报错,需要先获取,再删除,
- //因为remove()后,更新 lastRet=-1
- Student next = listIterator.next();
- System.out.println(next);
- }

hasNext() 是否还有下一个元素:通过cursor字段,判断是否到达集合边界
继承自Iterator
next() 返回下一个元素,继承自Iterator
hasPrevious 是否还有上一个元素
previous() 返回上一个元素
add () 增加元素
remove() 删除元素,继承自Iterator
- private class ListItr extends Itr implements ListIterator<E> {
- ListItr(int index) {
- super();
- cursor = index;
- }
-
- public boolean hasPrevious() {
- return cursor != 0;
- }
-
- public E previous() {
- checkForComodification();
- int i = cursor - 1;
- ...
- Object[] elementData = ArrayList.this.elementData;
- ...
- cursor = i;
- return (E) elementData[lastRet = i];
- }
-
- public void add(E e) {
- checkForComodification();
-
- try {
- int i = cursor;
- ArrayList.this.add(i, e);
- cursor = i + 1;
- lastRet = -1; //更新 lastRet
- expectedModCount = modCount; //执行完add后,更新 expectedModCount
- } catch (IndexOutOfBoundsException ex) {
- throw new ConcurrentModificationException();
- }
- }

- Collection<String> strC = new ArrayList<String>();
- strC.add("fa");
- strC.add("");
- strC.add("");
- strC.add("");
- strC.add("ffdasfa");
- for (String s : strC) {
- System.out.println(s);
- }
底层实现:
增强for循环,运行的时候,编译器为其生成1个Iterator迭代器,调用iterator的hasNext(),next()方法进行遍历
缺点: 和iterator迭代器一样,只读
1,只能单向遍历
2,遍历时,不能 向集合中 增加和修改元素,不能删除元素
优势:可以在 遍历集合的同时,对集合元素进行增删改
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。