迭代时删除离开元素并且不抛出并发 E

我遇到了这段代码,它在迭代时从列表中删除了项目,但它并没有抛出并发异常并在列表中留下了一些项目。


这是为什么?


例子:。


public class Application {

    public static void main(String[] args) {

        List<Integer> integerList = new ArrayList<Integer>();

        integerList.add(1);

        integerList.add(2);


        for (Integer integer : integerList) {

            removeInteger(integerList, integer);

        }


        System.out.println(integerList.toString()); // prints [2] as it was not removed (while it should be)

    }


    private static void removeInteger(List<Integer> integerList, Integer integer) {

        for (Integer integer1 : integerList) {

            if (integer.equals(integer1)) {

                int index = integerList.indexOf(integer);

                if (index >= 0) {

                    integerList.remove(index);

                }

            }

        }

    }

}

如果我将removeInteger方法更改为 useIterator而不是main我传递的副本,则integerList一切都按预期工作。


慕的地8271018
浏览 104回答 1
1回答

holdtom

首先,如果您向列表中添加更多元素,它仍然会失败并显示ConcurrentModificationException.由于发布的示例没有失败,我们必须看看内部发生了什么。如果您进行调试,您会在发布的示例中看到,两个循环仅迭代一次。删除内部循环(方法)中的元素removeInteger会耗尽两个迭代器。由于没有进一步的交互,因此不会导致错误。“仅”修改后的调用Iterator#next可能导致 ConcurrentModificationException。是的,但为什么它会耗尽它们呢?查看源代码ArrayList#Itr我们可以看到&nbsp;&nbsp;&nbsp;public&nbsp;boolean&nbsp;hasNext()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;cursor&nbsp;!=&nbsp;size; &nbsp;&nbsp;&nbsp;}只检查一个名为 的变量size。此变量size是 的属性ArrayList。当remove被调用时,该变量递减。因此,下次hasNext调用时,迭代器假定不再有新元素。旁注:cursor指向列表中的下一个元素。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java