1.迭代器概述
在集合遍历时候都需要或间接使用迭代器,增强for隐藏了迭代器而已。
2.先看下代码
package cn.jason05;
import java.util.ArrayList;
import java.util.ListIterator;
/**
* 这是迭代器的用法
*
* @author cassandra
*/
public class IteratorTest {
public static void main(String[] args) {
ArrayList<String> array = new ArrayList<>();
array.add("a");
array.add("b");
array.add("c");
ListIterator<String> i = array.listIterator();
//正常输出
while (i.hasNext()) {
String string = i.next();
System.out.println(string);
}
//添加元素
while (i.hasNext()) {
String string = i.next();
if (string.equals("b"))
array.add("d");
System.out.println(string);
}
}
}
在添加元素的时候就会抛出ConcurrentModificationException并发修改异常
原因(引用别人的观点)
其实,迭代器是采用了快速失败的原理,一旦发现自己遍历的集合被修改,就像增删程序把集合array进行修改,则报以上的错误。其实这种错误经常在多线程中出现,一个线程在遍历集合,突然另一个线程把集合中的数据进行篡改。这种现象肯定是不允许出现的,报以上错误就是为了防止多线程共享资源发生资源争夺问题。
解决方法:
如果真要移除增加元素,只能有两种方法。①通过迭代器来修改集合 ②通过集合修改
在看看下面代码
<span style="white-space:pre"> </span>String string = null;
for (ListIterator<String> it = array.listIterator(); it.hasNext(); System.out.println(string)) {
string = it.next();
if (string.equals("b"))
it.add("d");
}
System.out.println("array="+array);
输出结果是a,b,c
array=[a, b,d, c]
结果分析:
这是用迭代器直接更改了集合的元素,集合通过ListIterator迭代器增加了元素d。迭代器依赖集合,it.next()相当于把集合的元素复制了一份给了引用变量string,所以string的值还是复制那份值a,b,c,没有发生变化。
再看看另一段代码,估计又会让你意想不到。
<span style="white-space:pre"> </span>String string1 = null;
for (ListIterator<String> it = array.listIterator(); it.hasNext(); System.out.println(string1)) {
string1 = it.next();
if (string1.equals("b"))
string1 = "d";
}
System.out.println(<span style="font-family: Arial, Helvetica, sans-serif;">"array="+array</span>);
输出结果:a,d,c
array=[a, b,c]
结果分析:
集合并没有增删元素,所以没发生变化,只是集合复制那份元素发生了变化,把d赋值给了string1,所以string1输出的值是a,d,c
3.总结
1.要清楚迭代器的原理,增强for的原理。遍历集合时,要么通过迭代器增删元素要么通过集合增删元素。
2.迭代器增删元素时候,也是相当于在复制了一份值,这和值传参还是引用传参一样的道理。值传参是不影响原来的变量,引用传参会影响到原来的变量。