[英]Is it safe to add items to a linked list while iterating
在迭代时将项添加到LinkedList
是否安全?
class Worker {
final LinkedList<Foo> worklist = new LinkedList<>();
public void work() {
Iterator<Foo> iterator = worklist.iterator();
while (iterator.hasNext()) {
Foo foo = iterator.next();
doSomethingWith(foo);
}
}
public void doSomethingWith(Foo foo) {
// do something with foo
// and possibly add one (or more) foo's to the worklist
if (expression) {
worklist.add(new Foo());
}
}
}
如果没有,如何以安全有效的方式实施此行为?
请注意,这不是关于List
,而是关于LinkedList
。 如果它不安全,我会问有关替代方案。
不,这不安全。 以下代码将抛出ConcurrentModificationException
:
final LinkedList<Foo> worklist = new LinkedList<>();
worklist.add(new Foo());
Iterator<Foo> iterator = worklist.iterator();
while (iterator.hasNext()) {
Foo foo = iterator.next();
worklist.add(new Foo());
}
LinkedList
不会覆盖iterator()
,并且在AbstractSequentialList
定义的默认实现是调用listIterator()
,而LinkedList
会覆盖listIterator
。
引用LinkedList.listIterator
的文档:
list-iterator是快速失败的 :如果在创建Iterator之后的任何时候对列表进行结构修改,除了通过list-iterator自己的
remove
或add
方法之外,list-iterator将抛出ConcurrentModificationException
。
你想要的是明确使用ListIterator
而不是Iterator
,并使用ListIterator.add
:
final LinkedList<Foo> worklist = new LinkedList<>();
worklist.add(new Foo());
ListIterator<Foo> iterator = worklist.listIterator();
while (iterator.hasNext()) {
Foo foo = iterator.next();
iterator.add(new Foo());
}
新元素插入next()
返回的元素之前,因此对next()
后续调用不受影响。 如果要将新项添加到迭代中,可以在添加元素后调用previous()
(并忽略返回值)以向后移动光标。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.