1、Iterator
在创建的过程中,会对整个集合中所有元素打招呼,记录每一个元素的位置。
2、Iterator
在执行next
方法过程中,会按照初始条件一个个遍历
3、当前集合通过remove方
法,删除已经被Iterator
记录的元素时,时有可能使iterator
发生线程冲突。这是由于集合本身数据和当前Iterator
是操作的一个共享资源,不管哪一方操作元素,都存在影响对方操作元素的情况。
只有当影响到ArrayList
底层中modCount
数值,这样才会影响另一方操作的共享数据的情况。
当使用set()
方法不会影响底层的modCount
数值,代码不报错。
package com.reviewedu.bolo;
import java.util.ArrayList;
import java.util.Iterator;
public class Demo2 {
public static void main(String[] args) {
ArrayList<String> c = new ArrayList<String>();
c.add("烤羊腰");
c.add("香辣虾尾");
c.add("土豆牛肉");
c.add("大盘鸡");
c.add("麻辣香锅");
c.add("孜然羊肉");
Iterator<String> iterator = c.iterator();
System.out.println(c);
c.set(1, "香蕉");
c.set(2, "芒果干");
System.out.println(c);
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
}
}
运行结果为
[烤羊腰, 香辣虾尾, 土豆牛肉, 大盘鸡, 麻辣香锅, 孜然羊肉]
[烤羊腰, 香蕉, 芒果干, 大盘鸡, 麻辣香锅, 孜然羊肉]
烤羊腰 香蕉 芒果干 大盘鸡 麻辣香锅 孜然羊肉
Process finished with exit code 0
当使用remove
方法和add
方法时会影响到底层的modCount
数值。从而迭代器抛出异常。
package com.reviewedu.bolo;
import java.util.ArrayList;
import java.util.Iterator;
public class Demo2 {
public static void main(String[] args) {
ArrayList<String> c = new ArrayList<String>();
c.add("烤羊腰");
c.add("香辣虾尾");
c.add("土豆牛肉");
c.add("大盘鸡");
c.add("麻辣香锅");
c.add("孜然羊肉");
Iterator<String> iterator = c.iterator();
System.out.println(c);
c.remove("大盘鸡");
c.add(3, "芒果干");
System.out.println(c);
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
}
}
运行结果为
[烤羊腰, 香辣虾尾, 土豆牛肉, 大盘鸡, 麻辣香锅, 孜然羊肉]
[烤羊腰, 香辣虾尾, 土豆牛肉, 芒果干, 麻辣香锅, 孜然羊肉]
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
at java.util.ArrayList$Itr.next(ArrayList.java:859)
at com.reviewedu.bolo.Demo2.main(Demo2.java:27)
Process finished with exit code 1
可见相应下标位置数据已经替换但是迭代器遍历时会发生错误。
看底层源码
迭代器底层源码
例如replaceAll
方法也会改变这个数值
总结
由此可见只要是ArrayList
方法改变了modCount
数值都会发生迭代器遍历报错。