2017-09-07 77 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