有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在当前“while(iterator.hasNext())”循环中添加到迭代器

在下面的代码中,我希望迭代运行3次。一开始,迭代器有1个“next”,但在第一次迭代中,迭代器又增加了两个值,因此应该还有两个“next”,即iterator.hasNext()应该为真

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class Foo {

    public static void main(String[] args) {
        List<String> strings = new ArrayList<>();
        strings.add("A");
        ListIterator<String> iterator = strings.listIterator();
        int i = 0;
        while (iterator.hasNext()) {
            i++;
            String str = iterator.next();
            if (str.equals("A")) {
                iterator.add("B");
                iterator.add("C");
            }
          //  strings.remove(str);
          //  iterator = strings.listIterator();
        }
        System.out.println("The iteration was run " + i + " times");
    }
}

但它只运行一次。作为一种解决方法,我可以从原始列表中删除当前迭代,然后重置迭代器(注释行)。但为什么这是必要的?迭代器不应该已经知道它有更多的值要迭代吗


共 (1) 个答案

  1. # 1 楼答案

    Shouldn't the iterator already know that it has more values to iterate?

    不,不应该。如果你查阅add(){a1}的文档,你可以在那里找到下面的句子

    a subsequent call to next would be unaffected, and a subsequent call to previous would return the new element. (This call increases by one the value that would be returned by a call to nextIndex or previousIndex.)

    这表明添加新元素不会影响当前的循环流。另外,如果您查看ArrayListListIterator实现的源代码:

    ...
    public E next() {
        checkForComodification();
        int i = cursor;
        if (i >= SubList.this.size)
            throw new NoSuchElementException();
        Object[] elementData = ArrayList.this.elementData;
        if (offset + i >= elementData.length)
            throw new ConcurrentModificationException();
        cursor = i + 1;
        return (E) elementData[offset + (lastRet = i)];
    }
    
    public void add(E e) {
        checkForComodification();
    
        try {
            int i = cursor;
            SubList.this.add(i, e);
            cursor = i + 1;
            lastRet = -1;
            expectedModCount = ArrayList.this.modCount;
        } catch (IndexOutOfBoundsException ex) {
            throw new ConcurrentModificationException();
        }
    }
    

    cursor变量指向next()用于返回下一个元素的位置。如您所见,cursorSubList大小都会增加。所以,实际上,cursor被调整为跳过“旧”的下一个位置,而代之以“新”的下一个位置。每次调用add()时,cursor都会得到相应的调整。要获得新元素,您应该使用previous()或重新开始循环

    此外,您的案例可以如下所示:

        cursor
          |
          V 
    0     1
    A 
    

    在添加BC之后,cursor仍然指向一个不存在的元素:

        cursor
          |
          V 
    0 1 2 3
    A B C