2017-09-07 10 views
0

私はリストを持っています、私はストリームを使用してフィルタリングし、最初の10をつかみ、ユーザに表示したいと思います。 ボタンを押した後、その場所からストリームを続けたいと思います。コレクション後にjavaストリームを続行

List<MyObject> allResults = getResults(); 
allResults.stream() 
    .filter(this::someCrazyFiltering) 
    .limit(10) 
    .map(this::turnToDisplayItem) 
    .forEach(this::addDisplayItemToContainer); 

// some stuff.. 
onClick(() -> { 
    List<MyObject> allResults = getResults(); 
    allResults.stream() 
     .filter(this::someCrazyFiltering) 
     .skip(10) // will eventually be 10 * amount of times clicked. 
     .limit(10) 
     .map(this::turnToDisplayItem) 
     .forEach(this::addDisplayItemToContainer); 
}); 

しかし、問題があり、ここで私は(再び)フィルタと一致していないか、これまで多くの最初の10 +上でフィルタを実行するために持っています。

これまでのところ、私が持っている解決策のいくつかは、最後のアイテムのインデックスを保存するためにpeekを使用しています(プレスキップ)。

List<MyObject> allResults = getResults(); 
allResults.stream() 
    .filter(this::someCrazyFiltering) 
    .limit(10) 
    .peek(o -> this.storeIndex(o, allResults)) // This feels klunky 
    .map(this::turnToDisplayItem) 
    .forEach(this::addDisplayItemToContainer); 

onClick(() -> { 
    List<MyObject> allResults = getResults(); 
    allResults.stream() 
     .skip(this.storedIndexToSkip) // This being stored from storeIndex function above. 
     .filter(this::someCrazyFiltering) 
     .limit(10) 
     .peek(o -> this.storeIndex(o, allResults)) // Store again for next click; This STILL feels klunky 
     .map(this::turnToDisplayItem) 
     .forEach(this::addDisplayItemToContainer); 
}); 

誰ができれば、私は

(その後、個別の項目になります)、そこストリームで「インデックス」のようなものはありません、だから私はstoreIndex関数内allResults.indexOf(o)を行う必要があります知っているが、これのためのより良い仕組みを考えていますか? filter/limitの後にストリームから枝分かれすることができるように

ストリームを一括して無視して、ただ古いループに戻って、iを10回見つけたら、もう一度やり直してください。

+1

どこから 'getResults()'がデータを取得しますか? 'for'ループの使用には何も問題ありません。どこでもストリームAPIを強制しようとするよりもはるかに優れています。 – Kayaman

+0

それは重要ではなかったので、私はちょうどそれを 'getResults()'としてpsudocodeしました。別のアイデアは、10のものがマッチするまで、または私が最後までヒットするまで、何かを取得しようとしているイテレータをただ持っていたということです。しかし、イライザをしばらく "生きている"ない? – WORMSS

+1

それは重要です。 10000行のデータベースデータと100行のメモリ内データを扱う場合、実行する必要があることに大きな違いがあります。 – Kayaman

答えて

2

ストリームをイテレータに変換し、next()を10回呼び出すことができます。 Iteratorは各next()呼び出しで遅延評価されます。

List<MyObject> allResults = getResults(); 
Iterator<DisplayItem> it = allResults.stream() 
    .filter(this::someCrazyFiltering) 
    .map(this::turnToDisplayItem) 
    .iterator(); 

onClick(() -> { 
    int n = 0; 
    while(n < 10 && it.hasNext()){ 
     this.addDisplayItemToContainer(it.next()); 
    } 
}); 
+0

ストリームとイテレータの両方を混在させることはできませんでした。私はコメントのイテレータについて言及していましたが、フィルタリングとマッピングという面倒さのため大規模なファンではありませんでした。これは両方の世界の中で最高です。ありがとうございました。 – WORMSS

関連する問題