web-dev-qa-db-ja.com

JavaのIteratorとListIteratorが要素間を指すのはなぜですか?

ListIteratorのJavadoc は次のように述べています。

ListIteratorには現在の要素がありません。そのカーソル位置は常に、previous()の呼び出しによって返される要素とnext()の呼び出しによって返される要素の間にあります。

JavaのListIteratorが、現在の要素ではなく要素間を指すように実装されたのはなぜですか?これにより、getNext()getPrevious()を繰り返し呼び出す必要がある場合、クライアントコードの可読性が低下するようです。そのため、適切な理由があるはずです。

補足として、私は peekable-arraylistと呼ばれる小さなライブラリ を記述しました。これはArrayListIterator、およびListIteratorを拡張し、peekAtNext()およびpeekAtPrevious()メソッドは、次のように実装されています。

  @Override public synchronized T peekAtNext() {
     T t = next();
     previous();
     return t;
  }
9
glenviewjeff

私が知る限り、その理由はあなたが引用しなかったjavadocの部分にあります(私の強調は下にあります):

プログラマがリストをいずれかの方向にトラバースできるようにするリストのイテレータ、modify反復中にリストを...

ご覧のとおり、意図された目的は、リストの変更中に使用を許可することです。可能な変更には、要素の削除が含まれているようです。

ここで、イテレータのcurrent()になる要素を削除するとどうなるかを考えます。イテレータが現在の要素の概念を持っていると仮定すると、このコンテキストでは、current要素の概念なしでそれを実装する方法は、私にはかなり理にかなっています-その方法では、イテレータは要素の削除について心配する必要がないからです。


importantは、javadocがスレッド実装であるインターフェースの実装を必要としないことに注意することです。

  • そのため、異なるスレッドから行われたmodificationsの正しい処理を期待すべきではありません-そのため、実装は、アクセスの同期、可視性の保証などの追加の手段を提供する必要があります= Javaあたりのメモリモデル JSR 1

ListIteratorで可能なことは、反復時に同じスレッドから行われた変更を処理することです。すべてのイテレータがそうであるとは限りません ConcurrentModificationException javadocs は特にこれについて警告します:

...この例外は、オブジェクトが別のスレッドによって同時に変更されたことを常に示すわけではないことに注意してください。単一のスレッドがオブジェクトのコントラクトに違反する一連のメソッド呼び出しを発行した場合、オブジェクトはこの例外をスローする可能性があります。たとえば、スレッドがコレクションを直接変更しているときに、フェイルファストイテレータでコレクションを反復処理している場合、イテレータはこの例外をスローします...

12
gnat