我是靠谱客的博主 谦让羽毛,最近开发中收集的这篇文章主要介绍基于集合ArrayList遍历中为其添加新元素导致其报错的思考首先让我们看一个题目总结,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

首先让我们看一个题目

创建一个集合,存入两个元素,“唐三藏”" 孙悟空” ,遍历集合,如果发现遍历的元素是猪八戒,就向集合中添加一个“猪八戒.

看到这个问题,我们最先想到的就一定是通过遍历来判断是否是孙悟空,如果是就加入新的一个猪八戒

于是代码如下:

public class Test {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add("唐三藏");
        list.add("孙悟空");
        for(int i=0;i<list.size();i++){
            if(list.get(i).equals("孙悟空")){
                list.add("猪八戒");
            }
        }
        System.out.println(list);
        for (Object i : list) {
            if (i.equals("孙悟空")) {
                list.add("猪八戒");
            }
        }
        System.out.println(list);
        Iterator it = list.iterator();
        while (it.hasNext()) {
            if (it.next().equals("孙悟空")) {
                list.add("猪八戒");
            }
        }
        System.out.println(list);
    }
}

但是实际上,运行后我们发现,只有普通for循环才可以为其加入,其他均报错ConcurrentModificationExceptio,如下图所示:

在这里插入图片描述
这是为什么呢?这需要我们从源代码中查找答案,首先我们按住crtl点击进入Iteator的内部
Iterator源代码层
选中它后使用菜单中的Navigate中的Type Hierarchy
在这里插入图片描述
找到其中的一条关联项
在这里插入图片描述

点进去后我们发现他规定了两个变量,一个是预期变化次数另一个则是变化次数,而每次调用next函数是都要确认这两个是否一致,如果不一致则会直接抛错。
在这里插入图片描述

在这里插入图片描述
add源代码究其根源就是自身变化次数这个值在使用add中自增了:在这里插入图片描述

同理如增强for(因为他们的判定方法其实都是类似的),都是因为集合变化次数增长了,而生成迭代器的时候给的变化次数没有跟着变化,所以才会报错,所以我们不能在集合迭代器增强for中直接为本集合添加新元素,但是如果是修改呢?

代码如下:

public class Test {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add("唐三藏");
        list.add("孙悟空");
        Iterator it = list.iterator();
        while (it.hasNext()) {
            if (it.next().equals("孙悟空")) {
                list.set(1,"猪八戒");
            }
        }
        System.out.println(list);
    }
}

实例图如下:
在这里插入图片描述
修改的源代码:
在这里插入图片描述

可以看到修改可以,这个也好理解,元素改变而原始代码中变化次数没有改变,所以不会有问题。但是如果删除应该也会报错吧。

代码如下:

public class Test {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add("唐三藏");
        list.add("孙悟空");
        Iterator it = list.iterator();
        while (it.hasNext()) {
            if (it.next().equals("孙悟空")) {
                list.remove("孙悟空");
            }
        }
        System.out.println(list);
    }
}

实例图如下:
在这里插入图片描述

同样,也是因为长度与预期不同导致了这个报错,让我们看下集合的remove方法,进入后他要先判断是否为null不为null则会执行遍历并判定集合中符合的第一个元素,并调用fastRemove方法
在这里插入图片描述
fastRemove使用之后第一件事就是使其变化次数自增与预期变化次数不同了.所以调用next时候就会报错
在这里插入图片描述

总结

总的来说,ArrayList在遍历中无法添加或删除新元素的原因还是在于迭代器和增强for的预期变化次数是一开始就定好的无法改变,如果想在for与迭代器中添加或删除元素,不妨再生成一个集合获取他的原本值,如果达到一定条件,就在新集合中增删吧。

最后

以上就是谦让羽毛为你收集整理的基于集合ArrayList遍历中为其添加新元素导致其报错的思考首先让我们看一个题目总结的全部内容,希望文章能够帮你解决基于集合ArrayList遍历中为其添加新元素导致其报错的思考首先让我们看一个题目总结所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(35)

评论列表共有 0 条评论

立即
投稿
返回
顶部