Encodera

Thanks for reading!

Donate to the site — we work hard for you.

How to paginate a list

Short answer

A page is the part of the list starting at (page - 1) * size with length size. With a stream you get it via skip() and limit():

void main() {
    var items = IntStream.rangeClosed(1, 23).boxed().toList();
    int page = 3;
    int size = 10;
 
    var current = items.stream().skip((long) (page - 1) * size).limit(size).toList();
    IO.println(current);
}

Output:

[21, 22, 23]

Number of pages

The number of pages is division rounded up:

void main() {
    int total = 23;
    int size = 10;
 
    IO.println(Math.ceilDiv(total, size));
}

Output:

3

With subList

subList() does not create a stream and is faster, but you have to clamp the bounds yourself:

<T> List<T> page(List<T> items, int page, int size) {
    int from = Math.min((page - 1) * size, items.size());
    int to = Math.min(from + size, items.size());
    return items.subList(from, to);
}
 
void main() {
    var names = List.of("Anna", "Oleg", "Boris", "Ivan", "Maria");
 
    IO.println(page(names, 2, 2));
    IO.println(page(names, 5, 2));
}

Output:

[Boris, Ivan]
[]

Common mistake

Not clamping the end of the page to the list size. The last, incomplete page goes out of bounds:

void main() {
    var names = List.of("Anna", "Oleg", "Boris");
    IO.println(names.subList(2, 4));
}

Output:

Exception in thread "main" java.lang.IndexOutOfBoundsException: toIndex = 4

Functions used in this recipe

  • List.subList() — Returns the part of a list between two indexes.
  • Stream.skip() — Skips the first N elements of a stream.
  • Stream.limit() — Truncates a stream to its first N elements.
  • Math.ceil() — Rounds up to the nearest integer that is greater than or equal.

Thanks for reading!

Donate to the site — we work hard for you.