目录
遍历的3种方式
方式1:迭代器循环
Iterator迭代器
功能:
注意事项:
方法:
ListIterator迭代器
功能:
注意:
方法:
方式2:增强for循环
方式3:普通for循环
遍历的3种方式
1,迭代器循环
2,增强for循环
3,普通for循环
方式1:迭代器循环
迭代器创建后,最好立即使用,不然之后对集合进行的增删改操作会导致迭代器遍历报错
原因:
1,系统创建迭代器时,会初始化 字段 expectedModCount = modCount,迭代器遍历获取字段时,next()会先对该字段进行校验
2, 对集合进行的 任何增删 操作都会导致 modCount++,从而在迭代器遍历时,在expectedModCount == modCount 中返回false,导致报错
private class Itr implements Iterator{ 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(); } }
Iterator迭代器
功能:
1,单向遍历
2,遍历过程中,不能增加和修改元素
3,遍历过程中,只能使用 Iterator提供的remove() 删除元素,不能使用Collection.remove() 删除元素
注意事项:
删除元素前,需要先调用next(),否则会报错
因为remove()中,更新 lastRet=-1,而要调用remove(),会先校验lastRet<0,抛异常
范例:
Collectionc = new ArrayList (); 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 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();
}
}
ListIterator迭代器
描述: 弥补了Iterator迭代过程中,不能增加元素
功能:1,双向遍历
2,遍历过程中,可以使用迭代器方法,增删改集合元素
注意:
1,删除元素前,必须调用next(),否则会报错
因为remove()中,更新 lastRet=-1,而要调用remove(),会先校验lastRet<0,抛异常
2,下面代码中,如果没有调用next(),只是单纯的add(), 会导致死循环,直到内存溢出,引发错误
解决方案:
add() 和 next() 一起使用
范例:
ArrayList方法:c = new ArrayList (); 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 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{ 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(); } }
方式2:增强for循环
Collection strC = new ArrayList();
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,遍历时,不能 向集合中 增加和修改元素,不能删除元素
方式3:普通for循环
优势:可以在 遍历集合的同时,对集合元素进行增删改



