要求時にのみ戻り値が評価される、ある種の遅延イテレータを使用するための最良のアプローチは何ですか?
-
06-07-2019 - |
質問
import java.util.Collection;
import example.Event;
public interface Query
{
public boolean hasMore ();
public Collection<Event> getNext ( long count ) throws Exception;
}
これは、私が実装したいインターフェイスです。
実装は次のようになっているはずです:
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import example.Event;
import example.Query;
public class ListQuery implements Query {
public ListQuery(List<Event> events, String filter)
throws FilterParseException {
// events is the list of given events
// filter is a string representation of the filter to apply
}
public Collection<Event> getNext(long count) throws Exception {
// returns max. count next entries which match given filter
}
public boolean hasMore() {
// returns if there are more elements matching the given filter
}
}
私が考えているのは、hasMore()とgetNext()の関係です。どちらの場合も、フィルターがリストの要素に一致するかどうかを評価する必要があります。おそらく私は与えられたリストの実装を知らないので、高価な操作になるかもしれません。明らかに、イテレータからhasNext()を使用することはできません。イベントが指定された基準に一致するかどうかを確認する必要があるためです。現在の実装では、2つの異なるイテレータと現在の位置があります。getNext()のイテレータの位置がhasMore()のイテレータの位置よりも大きい場合、hasMore()のイテレータは上に移動します。
実際にやりたいことは、hasMore()に順番に使用する現在のイテレータを複製することですが、これは明らかに不可能です。
この問題のよりエレガントな解決策はありますか?
解決
getNext
実装では、戻り値を割り当てた後、適切なイベントが見つかるまでイテレータを進めることができます。このようにして、 hasMore
はイテレータで hasNext
を安全にテストして、 true
または false
のどちらを返すかを決定できます。
他のヒント
自分自身の拷問をやめる:-)、これを使うだけです:
Iterables.filter(Iterable、Predicate)
これらの問題は自動的に処理されます。
イテレータのみ、イテレータのみにデータがない場合は、対応するクラスのイテレータを参照してください。イテレータを自分で実装する必要がある場合は、同じパッケージでAbstractIteratorを拡張すると役立つ場合があります。
その後、結果のチャンクを本当に取得したい場合は、Itera * sクラスのpartition()メソッドを使用できます。
2つのイテレータさえ必要ないと思っています。 hasMore
呼び出しは、一致するものが見つかるまでずっと反復し、そこにとどまります(既に一致している要素が反復する場合は反復しません)。これで、 getNext
は同じイテレータを使用して、カウントに達するか、一致する要素が見つからなくなるまで、返されるコレクションを反復してデータを追加します。