Java - Creating a Paginated List I need to create a class which acts as a paginated list. My use case is like this:

I am writing a library which makes a service call to fetch a List&lt;obj&gt;. Since the List&lt;&gt; can be large, the service expects me to call with a PAGE_SIZE. The service has also provided me with a TPS of x which I need call it with.

I need to do two things:


Rate Limit my calls to the Service
Expose a PaginatedList&lt;> from the library so that any client can use the Library and rate limit as per their TPS.


I was wondering whether the way I am implementing this PaginatedList is correct or if there is a better way.

public MyPaginatedList {
  private static final PAGE_SIZE = 50;
  private ServiceClient client;
  private int pageToProcess = 0; //to keep track of which page we need to process next
  private List&lt;Data&gt; data; // this is what the library exposes to outside world
  public MyPaginatedList(ServiceClient client) {
    this.client = client;
  }

  public MyPaginatedList getDataList(){
    Servicerequest request = new ServiceRequest();
    request.setIndex(PAGE_SIZE*pageToProcess++); // fetch the next set of items

    this.data = client.APICall(request);
    return this; // we return the current object
  }
}


The public API exposed by this Library would use MyPaginatedList like this:

class Library {
  private ServiceClient client;

  public Library(ServiceClient client) {
    this.client = client;
  }
  public MyPaginatedList fetchData() {
    return new MyPaginatedList(client).getDataList();
  }
}


Any client of this library can use MyPaginatedList and make Rate Limited Calls like this.


MyPaginatedList resultData = new Library().fetchData();
while(true) {
  for(Data d: resultData.getData()) // loop over the list exposed by MyPaginatedlist
  ...
  }
  RateLimiter.acquire(); // use guava rate limiter, would block till a token is available
  resultData = resultData.getDataList();
  if(resultData.getData().isempty()) {
    break;
  }
}



Edit:-

3 straightforward approaches come to my mind - 


  
  The one described above. Where the PaginatedList would expose a way to fetch next pages (batch of elements or List&lt;&gt;)
  Let the Library expose 2 API's - 
  
  PaginatedList fetchData() -> client would call this one initially
  PaginatedList fetchNextPage(PaginatedList) -> client would call this
  for sub-sequent pages
  This one is slightly modified version of approach 2. Let library expose a modified fetchData()
  
  PaginatedList fetchData(PaginatedList list) -> initially client
  would need to create a new PaginatedList(), which would initialize
  it's state like pageToProcess = 0; This API kind of takes in the
  metadata associated with the service call to identify which page to
  get next
  


Any more suggestions or variations would be appreciated!
spring has the concept of paging and they do something like this:

public Page findAll(Pageable pageable);


where the Page interface has the following methods (trimmed):

getTotalElements()
getTotalPages()
isFirst()
isLast()
nextPageable()
previousPageable()


it also extends the iterable interface so you can loop like this:

Library library = new Library();
Pageable pageRequest = ...
Page&lt;T&gt; page;
do {
  page = library.getData(pageRequest);
  for (T t: page) {
    log.debug("T is {}", t);
  }
  pageRequest = page.nextPageable();
} while( !page.isLast() );


the most notable difference is that the page being requested is not stored as a state in the client library. by storing the state you make it harder to use the same instance from multiple places in the code.

see http://docs.spring.io/spring-data/rest/docs/1.1.x/reference/html/paging-chapter.html