收集后继续java流

时间:2017-09-07 14:03:26

标签: java java-stream

我有一个列表,我想使用流过滤,抓住前10个,并显示给用户。 按下按钮后..我想从该位置继续播放。

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 ??

之后分割出一个流

或者只是忽略所有流,然后回到旧的for-each循环并在找到10之后存储i

欢迎任何建议。

1 个答案:

答案 0 :(得分: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());
    }
});