Iterator

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

可见相应下标位置数据已经替换但是迭代器遍历时会发生错误。

看底层源码ArrayList底层源码
迭代器底层源码
迭代器底层源码

例如replaceAll方法也会改变这个数值
在这里插入图片描述

总结
由此可见只要是ArrayList方法改变了modCount数值都会发生迭代器遍历报错。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值