【问题标题】:ConcurrentModificationException When removing element using list iterator javaConcurrentModificationException 使用列表迭代器 java 删除元素时
【发布时间】:2019-09-11 04:58:44
【问题描述】:

即使使用迭代器,我在删除列表的第一个和第二个元素时也遇到问题。

我已阅读以下主题,但无法解决我的问题(那些是最相关的,但我也查看了其他材料):

ConcurrentModificationException when trying remove element from list

Iterating through a Collection, avoiding ConcurrentModificationException when removing objects in a loop

所以我的代码如下所示:

List<List<String>> list = cnf.read();
List<List<String>> nlist = new ArrayList<>();
for (List<String> l : list) {
    if (l.size() <= 3) {
        nlist.add(l);
    } else {
        int size = l.size();
        while (size > 3) {
            List<String> three = l.subList(0, 2);
            three.add("Y" + (count++));
            //Iterator itr = l.iterator();
            ListIterator itr = l.listIterator();
            int v = 0;
            while (itr.hasNext()) {
                itr.next();
                if (v == 0 || v == 1) {
                    itr.remove();
                    v++;
                }
            }
            l.add(0, "Y" + (count++));
            size--;
            nlist.add(three);
        }
        nlist.add(l);
    }
}
for (List<String> l : nlist) {
    System.out.println(l.toString());
    System.out.println(l.size());
}

我在此处的打印语句中收到 ConcurrentModificationException :

System.out.println(l.toString());

我也尝试在我的 2 个 for 循环中使用迭代器,但这似乎没有什么不同! 我是发布问题的新手,所以如果我做得对,请告诉我! 谢谢。

【问题讨论】:

  • 你熟悉界面java.util.ListIterator吗?根据其javadoc,它允许在遍历列表时修改列表。
  • @Abra 是的!我正在使用迭代器来执行 itr.remove()。这应该允许我从列表中删除我想要的项目。但是,它会导致异常。我的猜测是,这是因为它位于另一个循环(嵌套)中,所以它会导致问题。我不知道如何解决它。
  • 您发布的代码不包含ListIterator
  • @Abra 所以这行:Iterator itr = l.iterator();不是 ListIterator 而是简单的 Iterator?我现在正在检查它以找到解决方案。这可能是一个线索。
  • 即使使用 ListIterator it = l.listIterator();。我得到同样的例外。正如我从以下帖子中了解到的那样:techdifferences.com/… 这两种方法的主要区别在于列表迭代器允许您修改和元素并双向遍历列表。

标签: java list loops iterator


【解决方案1】:

经过长时间的调试,解决方法如下。

sublist 函数通过引用而不是值传递,由 ArrayList.subList 调用创建的子列表保持对原始列表的引用并直接访问其 elementData 数组。

因此,当向“三”列表添加元素时,我们会更改原始列表的状态。这发生在这里:

三个.add("Y" + (count++));

针对这种特定情况修复它的一种方法是按以下方式创建和初始化“三”列表:

                String one = l.get(0);
                String two = l.get(1);
                List<String> three = new ArrayList<>();
                three.add(one);
                three.add(two);
                three.add("Y" + (count));

这允许我们在不发生并发异常 (ConcurrentModificationException) 的情况下操作列表。但是,如果您正在处理大列表,我建议您使用另一种较少硬编码的方法来创建列表。

我会将此主题标记为已回答,并希望它对人们有所帮助。

【讨论】:

  • 不过,我不明白为什么会抛出 ConcurrentModificationExceptiontoString() 应该使用它自己的 Iterator 并且在调用 toString() 之后不会修改列表。所以仍然存在ConcurrentModificationException 来自哪里的问题。如果有人能回答,那就太好了。
  • @stonar96 我认为这是因为我们正在迭代“nlist”。迭代导致异常,因为它包含的列表以“错误的方式”更改。这是我最好的猜测,但我不是专业人士!
猜你喜欢
  • 2016-07-19
  • 2018-07-18
  • 1970-01-01
  • 2013-11-25
  • 1970-01-01
  • 2011-07-04
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多