在迭代时向链表添加项是否安全?



在迭代时向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 fail-fast:如果在Iterator创建后的任何时间,以除通过list- Iterator自己的removeadd方法之外的任何方式修改了list- Iterator,则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()(并忽略返回值)来向后移动光标。

相关内容

  • 没有找到相关文章

最新更新