【问题标题】:Is iterator.next modified if the underlying list is modified with LinkedList add method?如果使用 LinkedList add 方法修改了底层列表,是否修改了 iterator.next?
【发布时间】:2019-03-15 03:34:14
【问题描述】:
intLinkList = 2, 4, 6, 8, 10
Iterator itr = intLinkList.iterator()

假设迭代器正在迭代并且当前指向整数 6。

itr current item  = 6
itr previous item = 4
itr next item     = 8

当 itr 当前指向 Integer 6 时,我使用 Linklists 的 add(Object obj, int index) 方法在 Integer 6 和 Integer 8 之间添加/插入 Integer 7。

我了解此 itr 实例在此修改后无效,因为基础列表已被修改,因此 modCount != expectedModCount。

我的问题是: 使用 LinkedList 的 add 方法进行修改是否会更改 itr.next 指向的项目? 我做了一些阅读,我知道这会引发 ConcurrentModificationException。 但这并不能回答我的问题,如果在迭代器迭代时修改了基础列表,则修改了 itr.next 项。

【问题讨论】:

  • 需要注意的是,您可以使用ListIteratorsee here添加元素。

标签: java linked-list iterator listiterator


【解决方案1】:

使用 LinkedList 的 add 方法修改是否会改变 itr.next 指向的项目?

没有。

调用LinkedListadd 不会改变Iterator 的状态。一旦你调用了Iteratornext()方法,在迭代器计算下一个要返回的元素之前,它会检查修改并抛出ConcurrentModificationException

这是相关代码,来自AbstractList$Itr

    public E next() {
        checkForComodification(); // will throw ConcurrentModificationException
                                  // before the Iterator's state is changed
        try {
            int i = cursor;
            E next = get(i);
            lastRet = i;
            cursor = i + 1;
            return next;
        } catch (IndexOutOfBoundsException e) {
            checkForComodification();
            throw new NoSuchElementException();
        }
    }

【讨论】:

  • 谢谢,这回答了我的问题。在迭代列表时,如果您使用非迭代器方法修改底层列表,迭代器将不会根据这些新修改更新它的下一个/上一个指针。
【解决方案2】:

一个关键细节是 Java 只有原语和引用。

当您向列表或任何集合添加内容时,它是引用的副本。

如果您修改引用的对象,则不会修改集合,但如果您打印它可能会出现的内容。

如果对集合调用 add 或 remove,对于 LinkedList 和 ArrayList,迭代器不会被修改但不能再迭代(有一个例外)

如果您使用 CopyOnWriteArrayList,您可以修改集合并继续迭代,但迭代器看不到更改。

【讨论】:

  • 谢谢。我了解迭代器不能再通过这种修改进行迭代。我只对验证 itr.next 是否被修改感兴趣。您的回答帮助我了解在迭代发生时修改基础列表时 itr 实例的状态不会改变。
猜你喜欢
  • 2012-05-12
  • 2012-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-30
相关资源
最近更新 更多