Reputation: 12538
I am trying to create a simple pagination routine for values held in an ArrayList
. Basically what I want to do is render the first five elements in the ArrayList
at first go. And then when users click on Next (increment by another 5)
and Previous (decrease by 5)
.
My logic looks like this:
class foo
{
private static final int defaultStep = 5;
private int moveCounter;
private List<String> values;
public foo()
{
values = new ArrayList<String>();
values.add("Fiber Channel");
values.add("Copper Channel");
...
}
private void pageNext()
{
if (moveCounter > -1 && moveCounter < values.size())
{
int currentIndex = (moveCounter + 1);
renderValues(currentIndex, false);
}
}
private void pagePrevious()
{
if (moveCounter > -1 && moveCounter <= values.size())
{
renderValues(moveCounter-1, true);
}
}
private void renderValues(int startIndex, boolean isPreviousCall)
{
if (startIndex > -1)
{
StringBuilder html = new StringBuilder();
List<String> valuesToRender = new ArrayList<String>();
int checkSteps = 1;
while (startIndex < values.size())
{
valuesToRender.add(values.get(startIndex));
if (checkSteps == defaultStep) break;
startIndex++;
checkSteps++;
}
moveCounter = startIndex;
//TODO: Build html String
...
}
}
}
I have an issue with pagePrevious
call, can you guys help me build the valuesToRender
5-steps up values array
before adding the value to render to the valuesToRender
array.
I tried doing something like this also:
for (int start = startIndex, end = values.size() - 1; start < end; start++, end--)
{
if (isPreviousCall) valuesToRender.add(values.get(end));
else valuesToRender.add(values.get(start));
if (checkSteps == defaultStep) break;
checkSteps++;
}
But this doesn't seems to work neither. Can you guys spot and help me fix this issue. Thanks Guys.
Upvotes: 1
Views: 13558
Reputation: 3649
List<List<T>> partition = Lists.partition(list, pageSize);
Use the index as the page number to fetch page.
Upvotes: 0
Reputation: 495
Here is a simple java function for pagination. Note that the page
starts from 0 (first page)
public List<Object> pagedResponse(List<Object> allItems, int page, int limit){
int totalItems = allItems.size();
int fromIndex = page*limit;
int toIndex = fromIndex+limit;
if(fromIndex <= totalItems) {
if(toIndex > totalItems){
toIndex = totalItems;
}
return allItems.subList(fromIndex, toIndex);
}else {
return Collections.emptyList();
}
}
Upvotes: 1
Reputation: 591
Based on "pscuderi" solution here I've built a wrapping class that can be helpful for someone looking for this:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class PaginatedList<T> {
private static final int DEFAULT_PAGE_SIZE = 10;
private List<T> list;
private List<List<T>> listOfPages;
private int pageSize = DEFAULT_PAGE_SIZE;
private int currentPage = 0;
public PaginatedList(List<T> list) {
this.list = list;
initPages();
}
public PaginatedList(List<T> list, int pageSize) {
this.list = list;
this.pageSize = pageSize;
initPages();
}
public List<T> getPage(int pageNumber) {
if (listOfPages == null ||
pageNumber > listOfPages.size() ||
pageNumber < 1) {
return Collections.emptyList();
}
currentPage = pageNumber;
List<T> page = listOfPages.get(--pageNumber);
return page;
}
public int numberOfPages() {
if (listOfPages == null) {
return 0;
}
return listOfPages.size();
}
public List<T> nextPage() {
List<T> page = getPage(++currentPage);
return page;
}
public List<T> previousPage() {
List<T> page = getPage(--currentPage);
return page;
}
public void initPages() {
if (list == null || listOfPages != null) {
return;
}
if (pageSize <= 0 || pageSize > list.size()) {
pageSize = list.size();
}
int numOfPages = (int) Math.ceil((double) list.size() / (double) pageSize);
listOfPages = new ArrayList<List<T>>(numOfPages);
for (int pageNum = 0; pageNum < numOfPages;) {
int from = pageNum * pageSize;
int to = Math.min(++pageNum * pageSize, list.size());
listOfPages.add(list.subList(from, to));
}
}
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
for (int i = 1; i <= 62; i++) {
list.add(i);
}
PaginatedList<Integer> paginatedList = new PaginatedList<Integer>(list);
while (true) {
List<Integer> page = paginatedList.nextPage();
if (page == null || page.isEmpty()) {
break;
}
for (Integer value : page) {
System.out.println(value);
}
System.out.println("------------");
}
}
}
Upvotes: 4
Reputation: 36229
I would do it like this:
I'm not sure what renderValues does, and whether we have to substract 1 or maybe defaultStep from the upper bound of the moveCounter.
private void pageMove (int step)
{
moveCounter = moveCounter + step;
if (moveCounter < 0) moveCounter = 0;
if (moveCounter > values.size ()) moveCounter = values.size ();
renderValues (currentIndex, false);
}
private void pageNext ()
{
pageMove (defaultStep);
}
private void pagePrevious ()
{
pageMove (-defaultStep);
}
The first 3 lines could be packed into two big ternary experssions like so:
mc = ((mc + s) < 0) ? 0 : ((mc + s) > vs) ? vs : (mc + s);
but the 3 lines solution is better to follow.
Upvotes: 0
Reputation: 200158
Change
if (moveCounter > -1 && moveCounter <= archive.size())
{
renderValues(moveCounter-1, true);
}
to
if (moveCounter > 0 && moveCounter <= archive.size())
{
renderValues(moveCounter-1, true);
}
Upvotes: 1