编写一个方法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
来解决它。但我想知道为什么上面的代码不起作用?
编辑:
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);
}
}
}
同样的错误。
答案 0 :(得分:5)
在此迭代中,隐式创建了iterator
对象。当你有iterator
时,你可以只从迭代器中改变集合。在这种情况下,您将直接删除对象,这就是抛出此异常的原因。
创建迭代器,并使用迭代器删除对象:
iterator.remove(); // removes current element
答案 1 :(得分:2)
要了解ConcurrentModificationException
出现的原因,您将了解fail-fast迭代的概念。如果一个线程正在迭代一个集合,并且它意识到正在进行迭代时正在修改集合,那么迭代器将抛出一个异常,而不是“可能”导致代码中的任何完整性问题。
当然,并非所有迭代器都遵循这种方法,并且使用Java Iterator
几乎总能确保迭代在修改时永远不会失败。
要使用迭代器删除元素,请使用此代码
Iterator<String> iter = list.iterator();
while(iter.hasNext()) {
String obj = iter.next();
if(<removal_condition_here>) {
iter.remove();
}
}