イテレータが NoSuchElementException を発生させてループの実行を停止するときに foreach ループが考慮されないのはなぜですか?
説明させてください。
通常、反復子は hasNext と next という 2 つの重要なメソッドを提供する必要があります。反復する要素がこれ以上ない場合、次のメソッドは NoSuchElementException を発生させる可能性があります。hasNext メソッドは、コードを少しだけ改善するための構文シュガーのようなものです。重要なメソッドは実際には next であり、これは何らかの作業を行うべきメソッドですが、hasNext ではなく、hasNext が事前に呼び出されているという仮定なしで実装する必要があります。
次のような状況があるとします。
final Iterator<String> bogusIt01 = new Iterator<String>() {
public boolean hasNext() {
return true;
}
public String next() {
throw new NoSuchElementException("no such element");
}
public void remove() {
throw new UnsupportedOperationException("cannot remove element");
}
};
final Iterable<String> bogusPr01 = new Iterable<String>() {
public Iterator<String> iterator() {
return bogusIt01;
}
};
for (@SuppressWarnings("unused") String string:bogusPr01) {
// pass
}
これにより、NoSuchElementException が発生します。ループが終了することを期待しています。私はそれを間違っていますか?
私が質問している理由は、このモデルを使用すると、別の反復子をラップしてその出力に対して何らかの処理を行う反復子を作成することが非常に困難になるためです。次のシナリオを想像してみましょう。
Iterator1 <- これはオリジナルのイテレータで、問題ありません。
Iterator2 <- この反復子は Iterator1 をラップし、反復された要素の出力を変更します。
Iterator2 は次のように実装されます。
public boolean hasNext() {
return iterator1.hasNext();
}
public Object next() {
if (!iterator1.hasNext()) {
throw new NoSuchElementException("no such element");
}
Object nextValue = iterator1.next();
try {
// do something that could raise exception
} catch (Exception e) {
return this.next();
}
return productValue;
}
public void remove() {
throw new UnsupportedOperationException("cannot remove element");
}
そのような設計は、私には非常に理にかなっていますが、まったく不可能です.
これを行うより良い方法はありますか?