返回信息流代码1:这段代码会报一个java.util.ConcurrentModificationException
public class Test {
public static void main(String args[]){
List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
for (String i : list){
if (i.equals("a")){
list.remove("a");
}
}
}
}
代码2:这段代码就没问题了
public class Test {
public static void main(String args[]){
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
for (Integer i : list){
if (i == 2){
list.remove(list.indexOf(2));
}
}
for (Integer i : list){
System.out.print(i);
}
}
}
请问各位大大这是为什么?
这是一条镜像帖。来源:北邮人论坛 / java / #56440同步于 2017/5/31
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
一个java Iterator问题
zcy19941015
2017/5/31镜像同步18 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
但问题是第二个代码没错啊
【 在 fa520875 的大作中提到: 】
: 你直接删除一个元素 觉得没问题吗?这样他后面的元素不就前移了一位了吗
但问题是第二个代码没错啊
【 在 intmain 的大作中提到: 】
: 用迭代器迭代容器的同时还修改了容器(remove),会导致原有的迭代器失效
你的两段测试代码中都用到了foreach循环遍历list集合,实际上foreach循环是JavaC编译器提供的一个语法糖,在编译后会替换为迭代器的形式,也就是for(String str : list)会变为for(Iterator iter = list.iterator(); iter.hasNext(); str = iter.next()),ArrayList不是线程安全的,内部实际上维护了一个modCount变量,记录对List结构进行修改的次数,迭代器进行迭代时,先hasNext()判断还有下一个元素没被访问时,再next()迭代下一个元素,在next()内部,实际上会判断刚才提到的modCount变量是否还是预期值,如果不是,就说明在迭代时有线程(可能是当前迭代线程,就是你的第一个例子的情况,也有可能是其它线程)修改了集合结构(add,remove),就会直接抛出ConcurrentModificationException,终止迭代。
你的第二个例子,在第一个foreach中,会remove掉index为2的元素,而list中只有3个元素,也就是删掉了最后一个元素,而在开始第三次迭代时,同样会先hasNext()判断是否还有下一个元素,此时肯定为false,所以也就不会再next()了,迭代正常结束。
看一下ArrayList的源码就知道原因了。
ps:手机码字,可能不通顺,仅供参考啊……
发自「贵邮」
第二个例子中应该删除的是2吧,list.indexOf(2)返回的是2的索引值,list.remove(list.indexOf(2))应该是把2删除了吧,最后输出是1,3呀。
【 在 cbd 的大作中提到: 】
: 你的两段测试代码中都用到了foreach循环遍历list集合,实际上foreach循环是JavaC编译器提供的一个语法糖,在编译后会替换为迭代器的形式,也就是for(String str : list)会变为for(Iterator iter = list.iterator(); iter.hasNext(); str = iter.next()),ArrayList不是线程安全的,内部实际上维护了一个modCount变量,记录对List结构进行修改的次数,迭代器进行迭代时,先hasNext()判断还有下一个元素没被访问时,再next()迭代下一个元素,在next()内部,实际上会判断刚才提到的modCount变量是否还是预期值,如果不是,就说明在迭代时有线程(可能是当前迭代线程,就是你的第一个例子的情况,也有可能是其它线程)修改了集合结构(add,remove),就会直接抛出ConcurrentModificationException,终止迭代。
: 你的第二个例子,在第一个foreach中,会remove掉index为2的元素,而list中只有3个元素,也就是删掉了最后一个元素,而在开始第三次迭代时,同样会先hasNext()判断是否还有下一个元素,此时肯定为false,所以也就不会再next()了,迭代正常结束。
: 看一下ArrayList的源码就知道原因了。
: ...................