首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java如何在现有接口之上构建流

Java如何在现有接口之上构建流
EN

Stack Overflow用户
提问于 2018-11-24 21:30:50
回答 2查看 73关注 0票数 1

我有一个现有的接口,它允许我访问理论上无限大的集合,如下所示:

代码语言:javascript
复制
List<Element> retrieve(int start, int end);

//example
retrieve(5, 10); // retrieves the elements 5 through 10.

现在,我想在这个现有接口的基础上构建一个Java流,这样我就可以根据需要流尽可能多的元素,而无需一次请求一个大列表。

我该怎么做呢?

我查看了Java流的示例,我所能找到的只是如何从完全在内存中的集合创建流的示例。目前,我一次加载30个元素,并进行必要的处理,但如果我可以将逻辑抽象出来,而只返回一个流,则会更干净。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-11-24 21:53:51

代码语言:javascript
复制
class Chunk implements Supplier<Element> {
    private final Generator generator;
    private final int chunkSize;
    private List<Element> list = Collections.emptyList();
    private int index = 0;

    public Chunk(Generator generator, int chunkSize) {
        assert chunkSize > 0;
        this.generator = generator;
        this.chunkSize = chunkSize;
    }

    @Override
    public Element get() {
        if (list.isEmpty()) {
            list = generator.retrieve(index, index + chunkSize);
            index += chunkSize;
        }
        return list.remove(0);
    }
}

这里我假设retrieve返回一个可变列表。如果没有,则需要在此时创建一个新的ArrayList或等效的。

这可以用作Stream.generate(new Chuck(generator, 30))。它生成一个从索引0开始的无限流。您可以添加一个构造函数,该构造函数允许在有用的情况下设置起始索引。

票数 2
EN

Stack Overflow用户

发布于 2018-11-24 21:39:17

我想你不能编辑retrieve方法。

你可以这样做:

代码语言:javascript
复制
IntStream.iterate(1, x -> x + 1).mapToObj(x -> retrieve(x, x).get(0))

如果序列的某一项依赖于前一项,这意味着如果您想要n第四项,则将每个项重新计算到n

这稍微解决了这个问题,方法是将它分成100块:

代码语言:javascript
复制
IntStream.iterate(1, x -> x + 1).mapToObj(x -> retrieve(1 + (x - 1) * 100, x * 100)).flatMap(List::stream)

如果您可以编辑该界面后面的内容,您只需使用上面所述的Stream<Element>来返回一个IntStream.iterate

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53462529

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档