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:
3With 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 = 4Functions 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.