2017-09-07 79 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); 
}); 

我知道有作爲流的「指標」沒有這樣的事,所以我需要做allResults.indexOf(o)storeIndex函數裏面了,(那將是不同的項目)

,但如果任何人都可以想一個更好的機制呢?就像能夠在filter/limit之後分流一樣

或者只是忽略所有流一起,只是回到舊的每個循環,並存儲i一旦發現10?

歡迎任何建議。

+1

getResults()從哪裏獲取數據?使用'for'循環沒有任何問題。這比嘗試強制使用stream API更好。 – Kayaman

+0

這是不重要的,這就是爲什麼我只是將它編碼爲'getResults()'。另一個想法是隻有一個迭代器,我會繼續嘗試從10個事物匹配或者我已經達到最終結果..但是我不知道是否會有迭代器在一段時間內保持「活躍」的問題,或者不? – WORMSS

+1

這很重要。如果您正在處理10000行數據庫數據與100行某些內存數據,它對您應該做的事情有很大的影響。 – Kayaman

回答

2

您可以將您的流轉換爲迭代器並調用next()10次。每次next()調用時,Iterator都會被懶計算。

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