我有一个现有的接口,它允许我访问理论上无限大的集合,如下所示:
List<Element> retrieve(int start, int end);
//example
retrieve(5, 10); // retrieves the elements 5 through 10.现在,我想在这个现有接口的基础上构建一个Java流,这样我就可以根据需要流尽可能多的元素,而无需一次请求一个大列表。
我该怎么做呢?
我查看了Java流的示例,我所能找到的只是如何从完全在内存中的集合创建流的示例。目前,我一次加载30个元素,并进行必要的处理,但如果我可以将逻辑抽象出来,而只返回一个流,则会更干净。
发布于 2018-11-24 21:53:51
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开始的无限流。您可以添加一个构造函数,该构造函数允许在有用的情况下设置起始索引。
发布于 2018-11-24 21:39:17
我想你不能编辑retrieve方法。
你可以这样做:
IntStream.iterate(1, x -> x + 1).mapToObj(x -> retrieve(x, x).get(0))如果序列的某一项依赖于前一项,这意味着如果您想要n第四项,则将每个项重新计算到n。
这稍微解决了这个问题,方法是将它分成100块:
IntStream.iterate(1, x -> x + 1).mapToObj(x -> retrieve(1 + (x - 1) * 100, x * 100)).flatMap(List::stream)如果您可以编辑该界面后面的内容,您只需使用上面所述的Stream<Element>来返回一个IntStream.iterate。
https://stackoverflow.com/questions/53462529
复制相似问题