繁体   English   中英

迭代时将项添加到链表是否安全

[英]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自己的removeadd方法之外,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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM