Java如何在现有接口上构建流
我有一个现有接口,允许我访问理论上无限的集合,如下所示:Java如何在现有接口上构建流,java,java-stream,Java,Java Stream,我有一个现有接口,允许我访问理论上无限的集合,如下所示: List<Element> retrieve(int start, int end); //example retrieve(5, 10); // retrieves the elements 5 through 10. 列表检索(int开始,int结束); //范例 检索(5,10);//检索元素5到10。 现在,我想在这个现有接口的基础上构建一个Java流,这样我就可以在不需要一次请求一个大列表的情况下流式处理所需的
List<Element> retrieve(int start, int end);
//example
retrieve(5, 10); // retrieves the elements 5 through 10.
列表检索(int开始,int结束);
//范例
检索(5,10);//检索元素5到10。
现在,我想在这个现有接口的基础上构建一个Java流,这样我就可以在不需要一次请求一个大列表的情况下流式处理所需的任意多个元素
我该怎么做呢
我查看了Java流的示例,我所能找到的只是如何从完全位于内存中的集合创建流的示例。目前,我一次加载30个元素并进行必要的处理,但如果我能将该逻辑抽象出来,只返回一个流,那就更干净了。我假设您不能编辑
检索
方法
您可以这样做:
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)
如果您可以编辑该接口后面的内容,您可以使用上面的IntStream.iterate
,使其返回一个流{
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);
}
}
私人最终发电机;
私有最终整数块大小;
私有列表=Collections.emptyList();
私有整数指数=0;
公共块(生成器,int chunkSize){
断言chunkSize>0;
这个。发电机=发电机;
this.chunkSize=chunkSize;
}
@凌驾
公共元素get(){
if(list.isEmpty()){
list=generator.retrieve(index,index+chunkSize);
索引+=块大小;
}
返回列表。删除(0);
}
}
这里我假设retrieve
返回一个可变列表。如果没有,那么此时您需要创建一个新的ArrayList
或等效文件
这可以用作
Stream.generate(新卡盘(生成器,30))
。它生成一个从索引0开始的无限流。如果有用的话,您可以添加一个构造函数,允许设置起始索引。您将如何实现retrieve
btw?如果你的集合实现了随机访问
,这是显而易见的,但是如果它没有实现,那么如果你真的想返回一个流,为什么不简单地跳过(5)。限制(10)
?你可能想要流的一个静态工厂方法,比如。这不是一个没有短路操作的无限流吗?基本上,chunks范围应该是短路的参数。@nullpointer不想要一个无限流吗?OP只需在这之后添加一个限制
,并指定他想要的数量。