java.util.ListIteratorのドキュメントが嘘つきな件(´・ω・`)

 なんかはまったのでメモ。

あるときバグがあった

 とある要素の次の要素とか前の要素の情報を知りたくて、ListIteratorが使えるコンテナだったのでListIteratorを使ってhasNext()、next()、hasPrevious()、previous()してたんですが、prebious()は前の要素を取ってくるのにnext()が次の要素をとってこない。
 そういえばイテレーションするときもnext()の返り値を使うのでそんなものかと思ったんですが、previous()と対称性が取れていないのが気に入らない。

そうだドキュメントを読もう!

 最近ドキュメントちゃんと読んでなくて苦労したのでjavadocを見に行ったら。

next

E next()

リスト内の次の要素を返します。このメソッドは、リストを反復するために繰り返し呼び出される場合と、前後に移動するために previous の呼び出しと組み合わされる場合があります。next と previous の呼び出しを交互に行うと、繰り返し同じ要素が返されます。

定義:
    インタフェース Iterator<E> 内の next

戻り値:
    リストの次の要素
例外:
    NoSuchElementException - 繰り返し処理で次の要素がない場合

 と書いてある。次の要素ちゃうやないかヾ(#`Д´)ノ
 一方previousは
previous

E 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が信じられなくなってきたよママン。。。

追記

 JavaのIteratorは要素を指しているわけじゃないそうです。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA