Java、Googleコレクションライブラリ。 AbstractIteratorの問題?
質問
Googleコレクションライブラリを使用しています AbstractIterator でジェネレーターを実装します。そうしている間に問題に出くわしました。私はそれをより基本的なタイプに減らし、問題を再現しました。この削減は明らかに、Iterableを介して1からnumelementsまでカウントすることで、やり過ぎです。
基本的に次のコードでは、コメントなしのバージョンは機能しますが、コメント付きのバージョンは機能しません(最後の番号で終わるのではなく、null要素が最後に提供されます)。
何か間違っているのですか、それともライブラリの問題ですか?
private Iterable<Integer> elementGenerator(final int numelements) {
return new Iterable<Integer>() {
@Override public Iterator<Integer> iterator() {
return new AbstractIterator<Integer>(){
int localcount=0;
@Override protected Integer computeNext() {
if (localcount++ == numelements) return endOfData();
return localcount;
// return (localcount++ == numelements) ? endOfData() : localcount;
}
};
}
};
}
?:
の配置(たとえば、リターンのプレフィックスを付け、代わりに+1と比較する)をいじってみましたが、役に立ちませんでした。これについてのドキュメントを少し探してみましたが、何も見つかりませんでした。明らかに、?:
構文は便利であり、必要ではありませんが、それでも...
解決
異なる数値型の三項演算子、条件式を使用しているため、 NullPointerException
が発生します。 Javaには、3進表現で異なるタイプの数値を混合する場合の複雑なルールがあります: JLSセクション15.25
。
endOfData()
は Integer
を返すように指定されているのに対し、 localcount
は int
、Java unboxes endOfData()
の値。ただし、 endOfData()
がnullを返す場合、unboxing操作はnullポインター例外になります。
ifステートメントの使用を続けるか、localcountを Integer
として宣言できます。
他のヒント
問題は、3項演算子と組み合わせてpostincrement演算子を使用することにあると予想しています。そのため、2つのスニペットは完全に同等である必要があります。また、その時点でコードが呼び出されていない場合、AbstractIteratorの問題ではありません。