Imagine browsing a large storefront where loading every product up front would be wasteful. Each shopper should pull in one page at a time, only when the current page can no longer answer the next question. Two shoppers may use different page sizes and should never share paging state.
Product and ProductCatalog are already implemented for you. Your task is to implement only the Iterator pattern participants:
ProductCursor, the common contract for traversal and paging diagnostics.PaginatedCursor, the lazy iterator that owns its current page, offset, page position, fetch count, and transcript.
The cursor is constructed with the catalog and a page size. It can call the provided page(offset, limit) method to fetch a window and totalCount() to see whether more products exist. Opening a cursor must not fetch anything; the first call to hasNext() or next() that needs data triggers the first fetch.
The pre-implemented ProductCatalog exposes the following API to the tests:
ProductCatalog() creates a catalog holding no products and no cursors.boolean addProduct(int id, String name, double price) appends a product and returns true, or returns false once 30 products are stored.int totalCount() returns how many products are stored.int openCursor(int pageSize) opens a cursor that reads pageSize products per page and returns its id, counting from 1. A page size below 1 opens nothing and returns -1.boolean hasNext(int cursorId) returns whether a product is left, fetching the next page first if the current one is used up. An id that was never handed out returns false.String next(int cursorId) returns the next product and moves the cursor along, fetching a page first if the current one is used up. A cursor with nothing left returns "END", and an unknown id returns "NONE".int pagesLoaded(int cursorId) returns how many pages that cursor has fetched, or -1 for an unknown id.String transcript(int cursorId) returns that cursor's fetch log. Each fetch adds one Loading page N... entry, numbered from 1 for that cursor, and the entries are joined by " | ". A cursor that has fetched nothing returns "EMPTY", and an unknown id returns "NONE".
A product reads as Product{id=1, name='Laptop', price=999.99}. Formatting to exactly two decimal places is already handled by the provided Product class.
A page is fetched when a call needs a product the cursor does not already hold. Opening a cursor fetches nothing, and a cursor over an empty catalog never fetches. The final page may be shorter than pageSize.
Two cursors over the same catalog read at their own pace, each with its own page, fetch count, and transcript. Unknown cursor ids and invalid page sizes are handled by the provided catalog code.
Example 1:
Input:
Output:
Explanation: Opening the cursor fetches nothing, so the transcript is empty and the fetch count is zero. Page 1 arrives with the first next, and page 2 only when a third next runs past the end of page 1.
Example 2:
Input:
Output:
Explanation: Two cursors read the same four products at different page sizes. After three products each, the one reading two at a time has fetched two pages while the one reading three at a time has fetched one.
Constraints
1 <= id <= 10001 <= name.length <= 400.0 <= price <= 10000.0, given with at most two decimal places-5 <= pageSize <= 50- At most
30 products are stored in one catalog. - At most
100 calls in total are made across all methods.