ListIteratorのnext()とprevious()が同じ値を指す話

最近ListIteratorでハマったのでちょっと忘れないようメモです。

ハマったのはこんなシチュエーションです。

import java.util.LinkedList;
import java.util.ListIterator;

public class Main {
        public static void main(String[] args) {
            LinkedList<Integer> list = new LinkedList<Integer>();
            ListIterator<Integer> listItr;

            list.add(1);
            list.add(2);
            list.add(3);
            listItr = list.listIterator();

            System.out.println(listItr.next());         // 1が出力
            System.out.println(listItr.next());         // 2が出力
            System.out.println(listItr.previous());     // 1が出力されると思ったけど2が出力
            System.out.println(listItr.previous());     // 1が出力
            System.out.println(listItr.next());         // 2が出力されると思ったけど1が出力
            System.out.println(listItr.next());         // 2が出力
        }
}

next()の次にprevious()、previous()の次にnext()を呼ぶと予想と反して同じ値を返してきます。
Javaの公式ドキュメントを調べたらどうにもこれが正常な動作らしいので、なんでこうなるかもう少し調べてみました。

ListIterator初期状態はこんな感じになっています。

ここで1回next()を呼ぶとイテレータが指してる右側の値の1が返ってきて、イテレータが1つ進みます。

さらにもう1回next()を呼ぶと、イテレータの右側の2が返ってきて、イテレータが進んでこの状態になります。

ここでprevious()を呼ぶと、イテレータの左側の2が返ってきて、イテレータは1つ戻ります。

イテレータを進める前の右側の値と、進めた後の左側の値は同じ状態」、これがnext()とprevious()を交互に呼んだ時のからくりです。

コメント