Tim*_*Tim 5 java iterator linked-list listiterator
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());
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果没有,如何以安全有效的方式实施此行为?
请注意,这不是关于aList,而是关于a 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());
}
Run Code Online (Sandbox Code Playgroud)
LinkedList不覆盖iterator(),默认实现,定义AbstractSequentialList是调用listIterator(),并LinkedList覆盖listIterator.
引用以下文档LinkedList.listIterator:
list-iterator是快速失败的:如果在创建Iterator之后的任何时候对列表进行结构修改,除了通过list-iterator自己的
remove或add方法之外,list-iterator将抛出一个ConcurrentModificationException.
你想要的是使用explicitely a ListIterator而不是a 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());
}
Run Code Online (Sandbox Code Playgroud)
在由next()后续调用返回的元素之前插入新元素next()不受影响.如果要将新项添加到迭代中,可以previous()在添加元素后调用(并忽略返回值)以向后移动光标.