带分页的API的Stream vs Iterator

时间:2019-04-25 17:38:12

标签: java rest api java-stream

提供一个具有分页功能的Web API,该分页返回的 项多于一次可容纳的内存

HTTP GET /items?start=0&limit=10

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

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

将分页客户端隐藏在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);

...或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);

Stream用途更广。流的使用方式中是否有任何内容使其不适合此用例?喜欢:

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

1 个答案:

答案 0 :(得分:0)

我想发表评论,但有点太大了。

  

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

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

  

是否违反流的良好实践,因为执行新的页面请求以获取下一页中的项目,所以请求项#11可能因RuntimeException而失败?

不太确定我是否完全理解这一点,但似乎您担心同时有多个请求相同的数据。如果是这样,对于我来说,这对于流来说是不正常的,对于 just PageRequest来说,这是不正常的;毕竟,您只是读取数据-如果不存在,则返回一个空列表或部分列表或其他任何内容,但不要引发Exception。如果底层的PageRequest抛出该异常,请在仍然可以使用的包装器中对其进行处理。

请注意,通常您可以很容易地从Iterator -> StreamStream -> Iterator进行转换。即使这样,如果可以实现,我仍会坚持使用Stream方法。

相关问题