0

编写一个方法 removeEvenLength ,它接受一组字符串作为参数,并从集合中删除所有偶数长度的字符串。

我的解决方案:

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

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

输出:

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)

所以我可以通过创建一个Iterator. 但是我想知道为什么上面的代码不起作用?

编辑:

迭代器也不起作用:

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);
        }
    }
}

同样的错误。

4

2 回答 2

5

在这个迭代iterator中,对象被隐式创建。当您拥有时,iterator您可以仅从迭代器更改集合。在这种情况下,您将直接删除对象,这就是引发此异常的原因。

创建迭代器,并使用迭代器删除对象:

iterator.remove(); // removes current element
于 2013-02-05T21:54:32.663 回答
2

要了解为什么ConcurrentModificationException会发生,您将了解快速失败迭代的概念。如果一个线程正在迭代一个集合,并且它意识到该集合在迭代进行时正在被修改,那么迭代器将抛出一个异常,而不是“可能”在以后的代码中导致任何完整性问题。

当然,并不是所有的迭代器都遵循这种方法,并且使用 JavaIterator几乎总能确保迭代在修改时永远不会失败。

要使用迭代器删除元素,请使用此代码

Iterator<String> iter = list.iterator();
    while(iter.hasNext()) {
        String obj = iter.next();
        if(<removal_condition_here>) {
            iter.remove();
        }
    }
于 2013-02-05T21:56:38.660 回答