简体   繁体   English

为什么这段代码会引发ConcurrentModificationException?

[英]Why does this code throw ConcurrentModificationException?

Write a method removeEvenLength that takes a Set of strings as a parameter and that removes all of the strings of even length from the set. 编写一个方法removeEvenLength,该方法将一组字符串作为参数,并从该字符串集中删除所有长度相等的字符串。

My solution: 我的解决方案:

public static void removeEvenLength(Set<String> set) {
    for(String word : set) {
        if(word.length() % 2 == 0) {
            set.remove(word);
        }
    }
}

Input: [foo, buzz, bar, fork, bort, spoon, !, dude] 输入: [foo, buzz, bar, fork, bort, spoon, !, dude]

Output: 输出:

ConcurrentModificationException on line 2:
java.util.ConcurrentModificationException
    at java.util.TreeMap$PrivateEntryIterator.nextEntry(TreeMap.java:1115)
    at java.util.TreeMap$KeyIterator.next(TreeMap.java:1169)
    at removeEvenLength (Line 2)

So I can solve it by creating an Iterator . 所以我可以通过创建Iterator来解决它。 But I want to know why the above code doesn't work? 但是我想知道为什么上面的代码不起作用?

EDIT: 编辑:

Iterator doesn't work either: 迭代器也不起作用:

public static void removeEvenLength(Set<String> set) {
    Iterator<String> i = set.iterator();
    while(i.hasNext()) {
        String word = i.next();
        if(word.length() % 2 == 0) {
            set.remove(word);
        }
    }
}

Same error. 同样的错误。

In this iteration iterator object is implicitly created. 在此迭代中,将隐式创建迭代iterator对象。 When you have iterator you can change collection just from iterator. 当拥有iterator您可以仅从迭代器更改集合。 In this case you are removing object directly, that's why this exception is thrown. 在这种情况下,您将直接删除对象,这就是引发此异常的原因。

Create iterator, and remove object with iterator: 创建迭代器,并使用迭代器删除对象:

iterator.remove(); // removes current element

To understand why ConcurrentModificationException occurs, you will have understand the concept of fail-fast iteration. 要了解为什么会发生ConcurrentModificationException ,您将了解快速失败迭代的概念。 If a thread is iterating over a collection, and it realizes that the collection is being modified as the iteration is going on, the iterator will throw an exception rather than "probably" cause any integrity problems later on in the code. 如果线程在集合上进行迭代,并且意识到在迭代进行时正在修改集合,则迭代器将引发异常,而不是“可能”在以后的代码中引起任何完整性问题。

Of course, not all iterators follow this approach, and using the Java Iterator will almost always ensure that the iteration never fails on modification. 当然,并不是所有的迭代器都遵循这种方法,并且使用Java Iterator几乎总是可以确保迭代在修改时不会失败。

To remove an element using the iterator, use this code 要使用迭代器删除元素,请使用以下代码

Iterator<String> iter = list.iterator();
    while(iter.hasNext()) {
        String obj = iter.next();
        if(<removal_condition_here>) {
            iter.remove();
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么这段代码不抛出 ConcurrentModificationException? - Why does this code NOT throw a ConcurrentModificationException? 为什么这段代码会抛出 java ConcurrentModificationException? - Why does this code throw a java ConcurrentModificationException? 为什么这段代码不抛出 ConcurrentModificationException? - Why doesn't this code throw a ConcurrentModificationException? 为什么 iterator.remove 不抛出 ConcurrentModificationException - Why iterator.remove does not throw ConcurrentModificationException 为什么这段代码不会触发 ConcurrentModificationException? - Why this code does not trigger ConcurrentModificationException? 为什么 ArrayList 从多线程修改时不抛出 ConcurrentModificationException? - Why does ArrayList not throw ConcurrentModificationException when modified from multiple threads? 为什么it.next()抛出java.util.ConcurrentModificationException? - Why does it.next() throw java.util.ConcurrentModificationException? 为什么一个循环抛出一个ConcurrentModificationException,而另一个不抛出? - Why does one loop throw a ConcurrentModificationException, while the other doesn't? 为什么我的applet的paint方法抛出ConcurrentModificationException - Why does my applet's paint method throw a ConcurrentModificationException 为什么这段代码会在Java中导致ConcurrentModificationException? - Why does this code cause a ConcurrentModificationException in Java?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM