首页 > 技术文章 > 集合(4):集合中的并发修改异常以及解决方法

saowei 2021-12-27 23:31 原文

集合中的并发修改异常

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/*
    需求:
         现在有一个集合,集合中有些字符串的元素,
         判断一下里面有没有"bigdata"这个字符串
         如果有,我们就添加一个"yes"
 */
public class ListQuestion {
    public static void main(String[] args) {
        //创建List集合的对象
        List list = new ArrayList();
        //添加元素
        list.add("hello");
        list.add("world");
        list.add("java");
        list.add("bigdate");
        list.add("hadoop");

        //获取迭代器对象
        Iterator iterator = list.iterator();

        while (iterator.hasNext()){  //调用hasNext()方法判断迭代器下一位置是否有元素
            //调用next()方法来获取元素
            Object next = iterator.next();
            //向下转型
            String s = (String)next;
            //加入if()判断一下,bigdate是否等于s中的内容
            //(判断一下里面有没有"bigdata"这个字符串)
            if("bigdate".equals(s)){
                //如果是true,添加一个"yes"
                list.add("yes");
            }
        }
        System.out.println(list);
    }
}

输出结果:

image

结果出现 了异常,每一个异常也算一个类,可以通过API查看一下

在API中搜索ConcurrentModificationException

image

分析原因:

ConcurrentModificationException:并发修改异常
    当不允许这样的修改时,可以通过检测到对象的并发修改的方法来抛出此异常。

原因:
    迭代器是依赖于集合存在的,在遍历迭代器元素的时候,当我们判断成功后,
    往集合中添加了一个元素,但是呢,迭代器这个时候并不知道已经添加了元素,所以报错

    简单描述为:在迭代器遍历的时候,不能通过集合去修改元素

    解决办法:
        1、迭代器遍历,迭代器修改
        2、集合遍历,集合修改

迭代器遍历,迭代器修改

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

/*
    需求:
         现在有一个集合,集合中有些字符串的元素,
         判断一下里面有没有"bigdata"这个字符串
         如果有,我们就添加一个"yes"
 */
public class ListQuestion {
    public static void main(String[] args) {
        //创建List集合的对象
        List list = new ArrayList();
        //添加元素
        list.add("hello");
        list.add("world");
        list.add("java");
        list.add("bigdate");
        list.add("hadoop");

        //迭代器遍历,迭代器修改

        //获取List迭代器
      ListIterator listIterator = list.listIterator();

      while (listIterator.hasNext()){//调用hasNext()方法判断迭代器下一位置是否有元素
            Object next = listIterator.next();//调用next()方法来获取元素
            String s = (String)next;//向下转型

            // (判断一下里面有没有"bigdata"这个字符串)
            if("bigdate".equals(s)){
                listIterator.add("yes");//需求:如果是true,添加一个"yes"
            }
        }
        System.out.println(list);//[hello, world, java, bigdate, yes, hadoop]
        //因为迭代器遍历修改含有指针,指定的是bigtade,所以yes添加在bigtade后面
    }
}

集合遍历,集合修改(不需要调用迭代器)

import java.util.ArrayList;
import java.util.List;

/*
    需求:
         现在有一个集合,集合中有些字符串的元素,
         判断一下里面有没有"bigdata"这个字符串
         如果有,我们就添加一个"yes"
 */
public class ListQuestion {
    public static void main(String[] args) {
        //创建List集合的对象
        List list = new ArrayList();
        //添加元素
        list.add("hello");
        list.add("world");
        list.add("java");
        list.add("bigdate");
        list.add("hadoop");

        //集合遍历,集合修改
        for(int i = 1;i < list.size();i++){
            Object o = list.get(i); //利用get()来获取元素
            String s = (String)o;

            if("bigdate".equals(s)){
                list.add("yes");
            }
        }
        System.out.println(list);//[hello, world, java, bigdate, hadoop, yes]
        //因为集合遍历修改没有指针,yes将添加在末尾
    }
}

推荐阅读