Skip to content

Instantly share code, notes, and snippets.

@chakrit
Created February 23, 2021 08:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chakrit/2fdc041394306205aca133f6b35f834c to your computer and use it in GitHub Desktop.
Save chakrit/2fdc041394306205aca133f6b35f834c to your computer and use it in GitHub Desktop.
Converting Spring Page<T> to Stream<T>
package com.github.chakrit;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import java.util.function.Function;
import java.util.stream.Stream;
/**
* PageStreamer provides convenience methods for working with Page-inated result by converting them to Streams instead.
*
* This helps in situations where we cannot return Streams from JPA directly such as when we want to use Specification<T>
* but the API is more convenient to process in a stream fashion such as when generating reports or calculating complex
* statistics.
*
* Usage:
*
* PaymentRepository paymentRepository;
*
* // generate sales report by category, streaming, concurrently.
* var stream = PageStreamer.stream(paymentRepository::findAll)
* .collect(Collectors.groupingByConcurrent(Payment::getCategory),
* Collectors.reducing(0, Payment::getAmount, (a, b) -> a + b));
*/
public final class PageStreamer {
public static final int DEFAULT_BATCH_SIZE = 100;
public static <E> Stream<E> stream(Function<Pageable, Page<E>> pageSupplier) {
var pageable = PageRequest.of(0, DEFAULT_BATCH_SIZE);
var page = pageSupplier.apply(pageable);
if (page == null || !page.hasContent()) {
return Stream.empty();
}
return Stream.iterate(page, p -> !p.isEmpty(), p -> p.hasNext() ? pageSupplier.apply(p.nextPageable()) : Page.empty())
.flatMap(p -> p.getContent().stream());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment