快速失败 - 只有在删除元素时才会发生异常

时间:2015-10-28 12:08:12

标签: java collections concurrency

快速失败 :意味着如果他们检测到 自迭代开始以来,该集合已经发生了变化,他们将其置于未选中状态 ConcurrentModificationException

我写了一个测试示例来解决这个问题:

    String hi = "Hi";
    list.add(hi);
    list.add("Buy");
    System.out.println("list before: " + list);
    for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
        String string = iterator.next();
        list.add("Good");
    }

输出是:

list before: [Hi, Buy]
Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
    at java.util.ArrayList$Itr.next(ArrayList.java:831)
    at thread.CollectionTest.main(CollectionTest.java:19)

这是预料之中的。但是,删除元素时,不会抛出异常:

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

    String hi = "Hi";
    list.add(hi);
    list.add("Buy");
    System.out.println("list before: " + list);
    for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
        String string = iterator.next();
        list.remove(hi);
    }

输出:

list before: [Hi, Buy]
list after: [Buy]

为什么?这两种情况都是修改过的。

2 个答案:

答案 0 :(得分:1)

关键是检查修改不是hasNext(),而是next()。在你的&#34;删除&#34;在这种情况下,你可以抑制因为没有下一个元素而会抛出的next调用。

如果您在开头有3个元素,那么删除一个元素会导致hasNext为&#39; true&#39;。然后,以下next将抛出预期的异常。

JavaDoc指出&#34;快速失败&#34;功能基于&#34;尽力而为&#34;并且它仅用于检测错误,而不是真正依赖它来使程序正常运行。显然是因为像这样的副作用。

答案 1 :(得分:0)

抛出

<?php $recaptcha = new \ReCaptcha\ReCaptcha($secret); $resp = $recaptcha->verify($gRecaptchaResponse, $remoteIp); if ($resp->isSuccess()) { // verified! } else { $errors = $resp->getErrorCodes(); } ,您可以在迭代期间对列表进行一些修改。

在迭代期间在列表中进行修改之后,如果您尝试使用迭代器访问next()或remove(),那么它会验证modCount和expectedModCount和count不同,然后抛出ConcurrentModificationException

ConcurrentModificationException