带分页的 API 的流与迭代器

Joh*_*erg 5 java api rest java-stream

给定一个具有分页功能的 Web API,该 API一次返回的项目数量超出了内存容量

HTTP GET /items?start=0&limit=10
Run Code Online (Sandbox Code Playgroud)

我想构建一个易于使用的Java客户端。分页客户端很难使用

PageRequest pageRequest = new PageResut(0,10);
Page<Item> page = client.findItems(page);
while( !page.isLastPage() ) {
   Page<Item> nextPage = client.findItems( page.getNextPage() );
}
Run Code Online (Sandbox Code Playgroud)

将分页客户端隐藏在Iterator..

Iterator<Item> items = client.pagingItemsIterator();
// every 10 elements the iterator requests the next page behind the scenes i.e.
// the paging code of above is hidden in an iterator
items.forEachRemaining(this::dostuff);
Run Code Online (Sandbox Code Playgroud)

...或者Stream使 API 更易于使用

Stream<Item> items = client.pagingItemsStream();
// every 10 elements the stream requests the next page behind the scenes
// i.e. the paging code above is hidden in the stream supplier
items.forEach(this::dostuff);
Run Code Online (Sandbox Code Playgroud)

AStream更通用。流的使用方式是否存在任何使其不适合此用例的情况?喜欢:

  • 与在获取流中的最后一个项目时在幕后请求下一页相比,流是否假设所有项目都是已知的?
  • RuntimeException由于执行新页面请求以获取下一页中的项目,请求项目 #11 可能会失败,这是否违反了流的良好实践?

Eug*_*ene 2

我想将此作为评论,但有点太大了。

流是否假设所有项目都是已知的......

例如Files::lines,没有办法知道某个文件中的确切行数,因此底层实现以某种方式做到这一点......对于顺序流来说很容易,对于并行流来说 - 它们所做的只是缓冲直到至少1024缓冲了行(下一个缓冲区中+ 1024,依此类推)。所以,是的,没有已知大小的流实现绝对是可能的,即使该大小可以动态变化 - 尽管这在我看来也带来了很多其他问题。

由于执行新页面请求以获取下一页中的项目,请求项目 #11 可能会失败并出现 RuntimeException,这是否违反了流的良好实践?

不太确定我完全理解这一点,但似乎您担心对同一数据的多个同时请求。如果是这样,这对我来说对于流来说是不正常的,就像对于;来说是不正常的一样。PageRequest毕竟您只是读取数据 - 如果数据不存在,则返回空列表或部分列表或其他内容,但不要抛出异常。如果底层PageRequest抛出该异常,请将其放入您将拥有的包装器中。

请注意,如果需要,通常您可以轻松地从 aIterator -> Stream和 from进行转换。即便如此,如果你能实现的话,Stream -> Iterator我会坚持使用一种方法。Stream