【发布时间】:2022-12-14 01:05:38
【问题描述】:
问题:在 ArrayList 中添加、删除、修改项目的最佳(性能方面)解决方案是什么,同时避免在操作期间抛出 ConcurrentModificationException?
语境:根据我对这个问题的研究,手头的问题似乎没有任何直接的答案 - 大多数建议使用CopyOnWriteArrayList,但我的理解是不建议对于大型数组列表(我正在使用它,因此是问题的性能方面)。
因此,我的理解可以总结如下,但要确定是否正确/不正确:
重要说明:以下语句均假定操作是在同步块内完成的。
-
消除在
ArrayList的迭代过程中,应该使用Iterator来完成,因为如果在集合中间进行删除,for 循环会导致不可预知的行为。例子:
Iterator<Item> itemIterator = items.iterator();
while (itemIterator.hasNext()) {
Item item = itemIterator.next();
// check if item needs to be removed
itemIterator.remove();
}
- 对于添加操作,不能用
Iterator完成,但可以用ListIterator完成。例子:
ListIterator<Item> itemIterator = list.listIterator();
while(itemIterator.hasNext()){
\\ do some operation which requires iteration of the ArrayList
itemIterator.add(item);
}
- 对于添加操作时,不一定要使用
ListIterator(即简单地使用items.add(item)不会导致任何问题)。 - 对于添加遍历集合时的操作可以使用
ListIterator或 for 循环来完成,但不能使用Iterator。例子:
Iterator<Item> itemIterator = item.iterator();
while (itemIterator.hasNext()) {
\\ do some operation which requires iteration of the ArrayList
items.add(item); \\ NOT acceptable - cannot modify ArrayList while in an Iterator of that ArrayList
}
-
修改ArrayList 中的项目可以使用
Iterator或具有相同性能复杂度的 for 循环来完成(这是真的?).例子:
\\ iterator example
Iterator<Item> itemIterator = item.iterator();
while (itemIterator.hasNext()) {
Item item = itemIterator.next();
item.update(); // modifies the item within the ArrayList during iteration
}
\\ for loop example
for (Item item : items){
item.update();
}
Iterator 迭代期间的修改是否具有与 for 循环相同的性能?这些方法之间是否存在任何线程安全差异?
奖金问题:如果还需要同步块,使用 ArrayList 的 synchronizedList 进行添加/删除/修改操作与 for 循环与迭代器相比有什么优势?
【问题讨论】:
-
for循环有效地创建和使用Iterator。如果您允许在循环进行时修改列表,您将得到相同的异常。
标签: java performance arraylist concurrency thread-safety