Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的迭代器如何知道何时抛出ConcurrentModification异常_Java_Exception_Collections_Concurrentmodification_Listiterator - Fatal编程技术网

Java中的迭代器如何知道何时抛出ConcurrentModification异常

Java中的迭代器如何知道何时抛出ConcurrentModification异常,java,exception,collections,concurrentmodification,listiterator,Java,Exception,Collections,Concurrentmodification,Listiterator,我有下面的代码抛出ConcurrentModificationException,因为我在同一个列表上使用两个不同的迭代器,其中一个正在修改列表。因此,第二个迭代器在读取列表时抛出异常,因为其他迭代器修改了列表 List<Integer> list = new ArrayList<>(); populate(list);//A method that adds integers to list ListIterator<Integer&g

我有下面的代码抛出ConcurrentModificationException,因为我在同一个列表上使用两个不同的迭代器,其中一个正在修改列表。因此,第二个迭代器在读取列表时抛出异常,因为其他迭代器修改了列表

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

    populate(list);//A method that adds integers to list

    ListIterator<Integer> iterator1 = list.listIterator();
    ListIterator<Integer> iterator2 = list.listIterator();

    while (iterator1.hasNext()) {
        if(iterator1.next() < 5)
            iterator1.remove();
    }

    while (iterator2.hasNext()){
        if(iterator2.next() < 5) {
         //Call handler   
        }
    }

我的问题是,如果列表没有到达迭代器1删除的元素,迭代器2如何在内部知道列表已被其他迭代器修改?它是如何发现其他迭代器已经改变了列表的?一种方法是跟踪大小,但这不是原因,因为其他迭代器可以替换任何元素。

回答类似问题的好方法是查看源代码。搜索ConcurrentModificationException

你应该知道事情是这样运作的:

集合对象有一个修改计数,该计数从零开始,并在发生添加、删除或类似操作时增加。 创建迭代器对象时,我们将集合的当前修改计数存储在迭代器中。 每次使用迭代器时,它都会根据迭代器创建时获得的mod count检查集合的mod count。如果这些值不同,则引发异常。 在您的情况下,删除迭代器1对列表执行的操作更改列表的结构操作计数modCount。当iterator2被要求删除时,它会看到它的expectedModCount,它最初收到的是0,与列表的当前mod count不同

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

    populate(list);//A method that adds integers to list

    ListIterator<Integer> iterator1 = list.listIterator();
    ListIterator<Integer> iterator2 = list.listIterator();

    while (iterator1.hasNext()) {
        if(iterator1.next() < 5)
            iterator1.remove();
    }

    while (iterator2.hasNext()){
        if(iterator2.next() < 5) {
         //Call handler   
        }
    }

需要注意的是,It.remove是一种特殊情况。当迭代器自身执行删除操作时,其预期的ModCount会相应地调整,以与基础列表保持同步。

为什么您会在意?您在修改列表之前创建了迭代器。可能有一个脏标志,但是,再一次,为什么您希望这样的代码工作?我不希望这样的代码工作。但我很想知道这个场景是如何被检测到的。请使用免费提供的源代码!不知道这样的问题会受到处罚!我会记住这一点的,找到了方法。谢谢不客气。这里的源代码非常有用,变量的名称和注释也很酷。顺便说一句,我对答案又加了一点——我想有人投了反对票,因为我遗漏了迭代器本身执行删除操作的技术性问题。这并没有改变基本的想法,但在这里完成是件好事。