How to implement pagination on a list? [closed]
Asked Answered
S

2

23

Is there any library that can be used to implement paging for a list?

Let' assume I have a space of 10 lines, and the user can select if he wants to scroll forward or backward by page (thus +- 10 items). This might eg be controlled by -1, 0, +1.

This is probably much work to build a class that prevents scrolling backward/forward if there are not enough items to display, and to self-save the state on which page the user is currently.

So is there anything?

Symposium answered 30/10, 2013 at 16:16 Comment(9)
For web applications: JSF provides paging.Scriptorium
No not jsf, pure javaSymposium
I was just about to ask what kind of app it is. By "pure Java" do you mean a swing app or a console app?Reena
sorry, I meant console app (this is later to be placed inside an existing architecture, but that does not matter).Symposium
This kind of structure you need is called a 'zipper'. See en.wikipedia.org/wiki/Zipper_%28data_structure%29 , there are java implementations on github.Callean
Hm this "zipper" seems to be to be some sort of single-item back and forth. I'm rather looking into pagination...Symposium
Unless I'm missing your point, it shouldn't be that difficult. You need to remember the page you're on and the number of items per page. Then you can easily calculate the index of the starting element in the list as either max(0, page * items per page) and the ending element as min(list.size-1, start index + items per page)Azote
That's right @Grove , you should be able to use list.subList(fromIdx,toIdx) to get a 'view' of the whole list... if that's what you need. No library required.Reena
The problem with using sublist is: Say there are 1000 records in DB for the particular condition. Now, all the records are fetched and then sublist is applied on that list to extract the 10 records from it. Is there any other efficient way than this?Disparage
O
37

I've solved this before. I made a static getPages method that breaks a generic collection into a list of pages (which are also lists). I've provided the code below.

public static <T> List<List<T>> getPages(Collection<T> c, Integer pageSize) {
    if (c == null)
        return Collections.emptyList();
    List<T> list = new ArrayList<T>(c);
    if (pageSize == null || pageSize <= 0 || pageSize > list.size())
        pageSize = list.size();
    int numPages = (int) Math.ceil((double)list.size() / (double)pageSize);
    List<List<T>> pages = new ArrayList<List<T>>(numPages);
    for (int pageNum = 0; pageNum < numPages;)
        pages.add(list.subList(pageNum * pageSize, Math.min(++pageNum * pageSize, list.size())));
    return pages;
}
Ordinance answered 8/4, 2014 at 20:3 Comment(0)
B
51

Minor optimization, if you don't really want to create any new list at all.

/**
 * returns a view (not a new list) of the sourceList for the 
 * range based on page and pageSize
 * @param sourceList
 * @param page, page number should start from 1
 * @param pageSize
 * @return
 * custom error can be given instead of returning emptyList
 */
public static <T> List<T> getPage(List<T> sourceList, int page, int pageSize) {
    if(pageSize <= 0 || page <= 0) {
        throw new IllegalArgumentException("invalid page size: " + pageSize);
    }
    
    int fromIndex = (page - 1) * pageSize;
    if(sourceList == null || sourceList.size() <= fromIndex){
        return Collections.emptyList();
    }
    
    // toIndex exclusive
    return sourceList.subList(fromIndex, Math.min(fromIndex + pageSize, sourceList.size()));
}
Bradleybradly answered 26/4, 2016 at 2:14 Comment(3)
Just stumbled upon this. Why does the page start at 1? If I wanted to have it start at 0 how would the sublist query look like? I've tried and get out of bounds issues. Thanks!Dena
@Philban, the page is just a parameter, if yours is 0-index based, then update the validation and simply add +1 to it :), the "javadoc" is the key to avoid issues hereBradleybradly
Excellent thanks for the response @Kisna. I'm actually going to open a question related to this. Basically i have it working but if lets say the size of the list is 10 and I do page=1&size=10 (everything comes back as expected) BUT if I do page=10&size=10 I also get the entire collection of the list back. Any ideas?Dena
O
37

I've solved this before. I made a static getPages method that breaks a generic collection into a list of pages (which are also lists). I've provided the code below.

public static <T> List<List<T>> getPages(Collection<T> c, Integer pageSize) {
    if (c == null)
        return Collections.emptyList();
    List<T> list = new ArrayList<T>(c);
    if (pageSize == null || pageSize <= 0 || pageSize > list.size())
        pageSize = list.size();
    int numPages = (int) Math.ceil((double)list.size() / (double)pageSize);
    List<List<T>> pages = new ArrayList<List<T>>(numPages);
    for (int pageNum = 0; pageNum < numPages;)
        pages.add(list.subList(pageNum * pageSize, Math.min(++pageNum * pageSize, list.size())));
    return pages;
}
Ordinance answered 8/4, 2014 at 20:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.