【发布时间】:2012-07-22 09:05:30
【问题描述】:
我想避免收到ConcurrentModificationException。我该怎么做?
【问题讨论】:
-
这是我的错误,在我们为您提供解决方案之前,您应该在遇到异常的地方提供代码
我想避免收到ConcurrentModificationException。我该怎么做?
【问题讨论】:
您可以使用ListIterator,它在迭代过程中支持删除/添加方法。
ListIterator<Book> iter = books.listIterator();
while(iter.hasNext()){
if(iter.next().getIsbn().equals(isbn)){
iter.add(new Book(...));
}
}
【讨论】:
您可以使用带索引的 for 循环,而不是使用迭代器。例如:
int originalLength = list.length();
for (int i = 0; i < originalLength; i++) {
MyType mt = list.get(i);
//... processing
//... insertions
}
【讨论】:
add(T) 操作的最佳解决方案,这正是我们所要求的。
get(i) 时,都必须访问所有节点,直到到达节点 i。恕我直言,这不是一个好方法。
arraylist 标签。
您想使用ListIterator。您可以从任何类型的列表中获取其中一个,但为了提高效率,您可能希望从LinkedList 中获取一个。
import java.util.*;
class TestListIterator {
public static void main(String[]args) {
List<Integer> L = new LinkedList<Integer>();
L.add(0);
L.add(1);
L.add(2);
for (ListIterator<Integer> i = L.listIterator(); i.hasNext(); ) {
int x = i.next();
i.add(x + 10);
}
System.out.println(L);
}
}
打印[0, 10, 1, 11, 2, 12]。
【讨论】:
创建一个新列表并填充该列表。
List<MyType> originalList = ...
List<MyType> newList = new ArrayList<>(originalList);
for(MyType type : originalList)
{
// Some decisions
newList.add(new MyType());
}
【讨论】:
originalList = newList;。不过这并不重要,因为 JimN 的解决方案更适合 add(T) 操作。
有三种方法可以避免上述异常
您可以将列表转换为数组,然后对数组进行迭代。这种方法适用于中小型列表,但如果列表很大,则会对性能产生很大影响。
您可以在迭代时锁定列表,方法是将其放入同步块中。不推荐使用这种方法,因为它会失去多线程的好处。
如果您使用的是 JDK1.5 或更高版本,则可以使用 ConcurrentHashMap 和 CopyOnWriteArrayList 类。这是推荐的方法。
【讨论】:
ConcurrentModificationException。此异常发生在单线程代码中。我错过了什么吗?