ListIterator previous() 和 next() 结果

ListIterator previous() and next() result

结果是

A B C D

D C C2 B2 B A

为什么不是结果

A B B2 C D

D C C2 B2 B A 在第一个 while ?

我做了 li.add("B2") 如果 word.equals"B"。这只是 next() 和 previous() 之间的区别吗?我想知道答案。

public static void main(String[] args) {

    List<String> list = Arrays.asList("A", "B", "C", "D");
    list = new ArrayList<>(list);
    ListIterator<String> li = list.listIterator();
    String word;

    while (li.hasNext()) {
        word = li.next();
        System.out.print(word + '\t');
        if (word.equals("B"))
           li.add("B2");
    }

    System.out.println();

    while (li.hasPrevious()) {
        word = li.previous();
        System.out.print(word + '\t');
        if (word.equals("C"))
            li.add("C2");
    }
}

ListIterator#add 的 JavaDoc 指定了行为:

 * Inserts the specified element into the list (optional operation).
 * The element is inserted immediately before the element that
 * would be returned by {@link #next}, if any, and after the element
 * that would be returned by {@link #previous}, if any.  (If the
 * list contains no elements, the new element becomes the sole element
 * on the list.)  The new element is inserted before the implicit
 * cursor: a subsequent call to {@code next} would be unaffected, and a
 * subsequent call to {@code previous} would return the new element.

困惑在哪里?

参见ListIterator.add(E)

... The element is inserted immediately before the element that would be returned by next() ...

因此在您的第一次迭代中,添加的 B2 不会成为列表中的下一个。

https://docs.oracle.com/javase/7/docs/api/java/util/ListIterator.html

原因是,当您向迭代器添加元素时,这不会更改 next() 元素,而只会更改 previous()。因此,当您添加 "B2" 和 "C2" 时,它只会被 previous() 调用拾取。这就是为什么第一次迭代没有选择 B2 和 C2 而第​​二次向后迭代选择了它们。

我认为您的问题的答案就在这里 - https://docs.oracle.com/javase/7/docs/api/java/util/ListIterator.html#add(E)

The element is inserted immediately before the element that would be returned by next(), if any, and after the element that would be returned by previous(), if any.

The new element is inserted before the implicit cursor: a subsequent call to next would be unaffected, and a subsequent call to previous would return the new element.

在第一个循环中,当单词等于“B”时,隐式光标位于“B”和“C”之间,根据文档,新元素将被添加到它之前。

A    B       C     D
       ^   ^ 
      B2  cursor
 

您可以通过更改您的印刷品以使用 nextIndex 来查看列表变化

System.out.print(list.get(li.nextIndex()) + "["+ li.nextIndex()+ "]" +'\t');


while (li.hasNext()) {
    System.out.print(list.get(li.nextIndex()) + "["+ li.nextIndex()+ "]" +'\t');
    word = li.next();
    if (word.equals("B")) {
         li.add("B2");
    }
  }

System.out.println();

while (li.hasPrevious()) {
    word = li.previous();
    System.out.print(list.get(li.nextIndex()) + "["+ li.nextIndex()+ "]" +'\t');
    if (word.equals("C"))
        li.add("C2");
    }
}

这输出

A[0]    B[1]    C[3]    D[4]     
D[4]    C[3]    C2[3]   B2[2]   B[1]    A[0]