なんかはまったのでメモ。
あるときバグがあった
とある要素の次の要素とか前の要素の情報を知りたくて、ListIteratorが使えるコンテナだったのでListIteratorを使ってhasNext()、next()、hasPrevious()、previous()してたんですが、prebious()は前の要素を取ってくるのにnext()が次の要素をとってこない。
そういえばイテレーションするときもnext()の返り値を使うのでそんなものかと思ったんですが、previous()と対称性が取れていないのが気に入らない。
そうだドキュメントを読もう!
最近ドキュメントちゃんと読んでなくて苦労したのでjavadocを見に行ったら。
next
E next()
リスト内の次の要素を返します。このメソッドは、リストを反復するために繰り返し呼び出される場合と、前後に移動するために previous の呼び出しと組み合わされる場合があります。next と previous の呼び出しを交互に行うと、繰り返し同じ要素が返されます。 定義: インタフェース Iterator<E> 内の next 戻り値: リストの次の要素 例外: NoSuchElementException - 繰り返し処理で次の要素がない場合
と書いてある。次の要素ちゃうやないかヾ(#`Д´)ノ
一方previousは
previousE previous()
リストの前の要素を返します。このメソッドは、リストを逆方向に反復するために繰り返し呼び出される場合と、前後に移動するために next の呼び出しと組み合わされる場合があります。next と previous の呼び出しを交互に行うと、繰り返し同じ要素が返されます。 戻り値: リストの前の要素 例外: NoSuchElementException - 繰り返し処理で前の要素がない場合
と書いてある。その通り動いているので何も言えない(´・ω・`)
javadocが正しいとするとAndroidのCopyOnWriteArrayListが返すListIteratorがおかしい。
そしてAndroidへ
例によってICSのr1のソースを見てみるとCopyOnWriteArrayListのListIteratorはCowIteratorが返すらしい。CowIteratorのnextとpreviousの実装が以下の通り。
@SuppressWarnings(\"unchecked\") public E next() { if (index < to) { return (E) snapshot[index++]; } else { throw new NoSuchElementException(); } } @SuppressWarnings(\"unchecked\") public E previous() { if (index > from) { return (E) snapshot[--index]; } else { throw new NoSuchElementException(); } }
と、まさしく実装の通り動いてたということのようです。
おぼれる者はJDKをも掴む
AndroidのListIteratorがjavadocに沿ってないのはわかった。じゃあJDKどうなの?
これでJDKが同じ動きだとしたら僕はjavadocのことを許せそうにないよ......。
ということでJDK6のソースを落としてきてCopyOnWriteArrayListこんにちわ。COWIteratorとか似たような名前のクラスを見つけて覗いてみたら。
public E next() { if (! hasNext()) throw new NoSuchElementException(); return (E) snapshot[cursor++]; } public E previous() { if (! hasPrevious()) throw new NoSuchElementException(); return (E) snapshot[--cursor]; }
神は死んだ。。。
前にも誤訳的な何かがあったりしたしもうそろそろjavadocが信じられなくなってきたよママン。。。