From 8a74215ecf3b1d57ec874ab9ae6f1ff637cf98b8 Mon Sep 17 00:00:00 2001 From: Zorglube Date: Mon, 25 Oct 2021 18:31:23 +0200 Subject: [PATCH 01/10] Add PageCollector --- .../data/util/PageCollectors.java | 278 ++++++++++++++++++ .../PageCollectorsToFilteredPageTest.java | 84 ++++++ ...ageCollectorsToFilteredSortedPageTest.java | 99 +++++++ .../data/util/PageCollectorsToPageTest.java | 72 +++++ .../util/PageCollectorsToSortedPageTest.java | 82 ++++++ 5 files changed, 615 insertions(+) create mode 100644 src/main/java/org/springframework/data/util/PageCollectors.java create mode 100644 src/test/java/org/springframework/data/util/PageCollectorsToFilteredPageTest.java create mode 100644 src/test/java/org/springframework/data/util/PageCollectorsToFilteredSortedPageTest.java create mode 100644 src/test/java/org/springframework/data/util/PageCollectorsToPageTest.java create mode 100644 src/test/java/org/springframework/data/util/PageCollectorsToSortedPageTest.java diff --git a/src/main/java/org/springframework/data/util/PageCollectors.java b/src/main/java/org/springframework/data/util/PageCollectors.java new file mode 100644 index 0000000000..2f727c96bb --- /dev/null +++ b/src/main/java/org/springframework/data/util/PageCollectors.java @@ -0,0 +1,278 @@ +package org.springframework.data.util; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.BinaryOperator; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.stream.Collector; +import java.util.stream.Collector.Characteristics; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; + +public final class PageCollectors { + + private static final Set characteristics = Collections.emptySet(); + + /** + * Reduce the {@link Stream} as {@link Page} based on the {@link Pageable} + * information. + * + * @param + * @param p + * @return a {@link Page} containing a subset of the {@link Stream} + */ + public static Collector, Page> toPage(final Pageable p) { + return new PageCollectorImpl<>(p); + } + + private static class PageCollectorImpl implements Collector, Page> { + + Pageable p; + + public PageCollectorImpl(final Pageable p) { + this.p = Objects.requireNonNull(p); + } + + @Override + public Set characteristics() { + return characteristics; + } + + @Override + public Supplier> supplier() { + return ArrayList::new; + } + + @Override + public BiConsumer, T> accumulator() { + return List::add; + } + + @Override + public BinaryOperator> combiner() { + return (left, right) -> { + left.addAll(right); + return left; + }; + } + + @Override + public Function, Page> finisher() { + return t -> { + final int pageNumber = p.getPageNumber(); + final int pageSize = p.getPageSize(); + final int fromIndex = Math.min(t.size(), pageNumber * pageSize); + final int toIndex = Math.min(t.size(), (pageNumber + 1) * pageSize); + + return new PageImpl<>(t.subList(fromIndex, toIndex), p, t.size()); + }; + } + + } + + /** + * Reduce the {@link Stream} as {@link Page} based on the {@link Pageable} + * information. + * + * @param + * @param p + * @return a {@link Page} containing a subset of the {@link Stream} sort + * following the {@link Comparator} + */ + public static Collector, Page> toSortedPage(final Pageable p, final Comparator c) { + return new SortedPageCollectorImpl<>(p, c); + } + + private static class SortedPageCollectorImpl implements Collector, Page> { + + Pageable p; + Comparator c; + + public SortedPageCollectorImpl(final Pageable p, final Comparator c) { + this.p = Objects.requireNonNull(p); + this.c = Objects.requireNonNull(c); + } + + @Override + public Set characteristics() { + return characteristics; + } + + @Override + public Supplier> supplier() { + return ArrayList::new; + } + + @Override + public BiConsumer, T> accumulator() { + return List::add; + } + + @Override + public BinaryOperator> combiner() { + return (left, right) -> { + left.addAll(right); + return left; + }; + } + + @Override + public Function, Page> finisher() { + return t -> { + final int pageNumber = p.getPageNumber(); + final int pageSize = p.getPageSize(); + final int fromIndex = Math.min(t.size(), pageNumber * pageSize); + final int toIndex = Math.min(t.size(), (pageNumber + 1) * pageSize); + + final List data = t.subList(fromIndex, toIndex); + data.sort(c); + + return new PageImpl<>(data, p, t.size()); + }; + } + + } + + /** + * Reduce the {@link Stream} as {@link Page} based on the {@link Pageable} + * information.
+ * + * The {@link Stream} is filtered before subset of data + * isolated + * + * @param + * @param p + * @return a {@link Page} containing a subset of the {@link Stream} + */ + public static Collector, Page> toFilteredPage(final Pageable p, final Predicate f) { + return new FilteredPageCollectorImpl<>(p, f); + } + + private static class FilteredPageCollectorImpl implements Collector, Page> { + + Pageable p; + Predicate f; + + public FilteredPageCollectorImpl(final Pageable p, final Predicate f) { + this.p = Objects.requireNonNull(p); + this.f = Objects.requireNonNull(f); + } + + @Override + public Set characteristics() { + return characteristics; + } + + @Override + public Supplier> supplier() { + return ArrayList::new; + } + + @Override + public BiConsumer, T> accumulator() { + return List::add; + } + + @Override + public BinaryOperator> combiner() { + return (left, right) -> { + left.addAll(right); + return left; + }; + } + + @Override + public Function, Page> finisher() { + return t -> { + final List data = t.stream().filter(f).collect(Collectors.toList()); + + final int pageNumber = p.getPageNumber(); + final int pageSize = p.getPageSize(); + final int fromIndex = Math.min(data.size(), pageNumber * pageSize); + final int toIndex = Math.min(data.size(), (pageNumber + 1) * pageSize); + + return new PageImpl<>(data.subList(fromIndex, toIndex), p, t.size()); + }; + } + + } + + /** + * Reduce the {@link Stream} as {@link Page} based on the {@link Pageable} + * information.
+ * + * The {@link Stream} is filtered then sorted then the subset of data + * isolated + * + * @param + * @param p + * @return a {@link Page} containing a subset of the {@link Stream} + */ + public static Collector, Page> toFilteredSortedPage(final Pageable p, final Predicate f, + final Comparator c) { + return new FilteredSortedPageCollectorImpl<>(p, f, c); + } + + private static class FilteredSortedPageCollectorImpl implements Collector, Page> { + + Pageable p; + Predicate f; + Comparator c; + + public FilteredSortedPageCollectorImpl(final Pageable p, final Predicate f, final Comparator c) { + this.p = Objects.requireNonNull(p); + this.f = Objects.requireNonNull(f); + this.c = Objects.requireNonNull(c); + } + + @Override + public Set characteristics() { + return characteristics; + } + + @Override + public Supplier> supplier() { + return ArrayList::new; + } + + @Override + public BiConsumer, T> accumulator() { + return List::add; + } + + @Override + public BinaryOperator> combiner() { + return (left, right) -> { + left.addAll(right); + return left; + }; + } + + @Override + public Function, Page> finisher() { + return t -> { + final List data = t.stream().filter(f).sorted(c).collect(Collectors.toList()); + + final int pageNumber = p.getPageNumber(); + final int pageSize = p.getPageSize(); + final int fromIndex = Math.min(data.size(), pageNumber * pageSize); + final int toIndex = Math.min(data.size(), (pageNumber + 1) * pageSize); + + return new PageImpl<>(data.subList(fromIndex, toIndex), p, t.size()); + }; + } + + } + +} diff --git a/src/test/java/org/springframework/data/util/PageCollectorsToFilteredPageTest.java b/src/test/java/org/springframework/data/util/PageCollectorsToFilteredPageTest.java new file mode 100644 index 0000000000..e42725d18b --- /dev/null +++ b/src/test/java/org/springframework/data/util/PageCollectorsToFilteredPageTest.java @@ -0,0 +1,84 @@ +package org.springframework.data.util; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertIterableEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +public class PageCollectorsToFilteredPageTest { + + private List ints; + private int size; + + @BeforeEach + void init() { + final Random rand = new Random(); + size = rand.nextInt(10000); + ints = IntStream.range(0, size).mapToObj(i -> rand.nextInt()).collect(Collectors.toList()); + } + + @Test + void fullPage() { + final Pageable pageable = Pageable.ofSize(size); + final Page page = ints.stream().collect(PageCollectors.toFilteredPage(pageable, i -> i > 0)); + + assertEquals(size, page.getSize()); + assertTrue(page.getContent().size() <= size); + for (final Integer element : page.getContent()) { + assertTrue(element > 0); + } + } + + @Test + void emptyPage() { + final Pageable pageable = Pageable.ofSize(size); + final Page page = Collections.emptyList().stream() + .collect(PageCollectors.toFilteredPage(pageable, i -> i > 0)); + + assertEquals(size, page.getSize()); + assertTrue(page.getContent().isEmpty()); + } + + @Test + void secondPage() { + final Pageable pageable = Pageable.ofSize(size / 4).withPage(2); + final Page page = ints.stream().collect(PageCollectors.toFilteredPage(pageable, i -> i < 0)); + + assertEquals(size / 4, page.getSize()); + assertTrue(page.getContent().size() <= size); + for (final Integer element : page.getContent()) { + assertTrue(element < 0); + } + } + + @Test + void checkData() { + final List datas = Arrays.asList("un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf", + "dix"); + + final int size = datas.size(); + final Pageable pageable = Pageable.ofSize(size / 2).withPage(0); + final Page page = datas.stream().collect(PageCollectors.toFilteredPage(pageable, t -> t.contains("i"))); + + assertEquals(size / 2, page.getSize()); + assertEquals(size / 2, page.getContent().size()); + for (final String string : page.getContent()) { + assertTrue(string.contains("i")); + assertFalse(!string.contains("i")); + } + assertIterableEquals(page.getContent(), Arrays.asList("trois", "cinq", "six", "huit", "dix")); + } + +} diff --git a/src/test/java/org/springframework/data/util/PageCollectorsToFilteredSortedPageTest.java b/src/test/java/org/springframework/data/util/PageCollectorsToFilteredSortedPageTest.java new file mode 100644 index 0000000000..77f8312bcb --- /dev/null +++ b/src/test/java/org/springframework/data/util/PageCollectorsToFilteredSortedPageTest.java @@ -0,0 +1,99 @@ +package org.springframework.data.util; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertIterableEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +public class PageCollectorsToFilteredSortedPageTest { + + private List ints; + private int size; + + @BeforeEach + void init() { + final Random rand = new Random(); + size = rand.nextInt(10000); + ints = IntStream.range(0, size).mapToObj(i -> rand.nextInt()).collect(Collectors.toList()); + } + + @Test + void fullPage() { + final Pageable pageable = Pageable.ofSize(size); + final Page page = ints.stream() + .collect(PageCollectors.toFilteredSortedPage(pageable, i -> i > 0, Integer::compare)); + + assertEquals(size, page.getSize()); + assertTrue(page.getContent().size() <= size); + + final List content = page.getContent(); + for (final Integer element : content) { + assertTrue(element > 0); + } + + for (int j = 1; j < content.size(); j++) { + assertTrue(Integer.compare(content.get(j - 1), content.get(j)) < 0); + } + } + + @Test + void emptyPage() { + final Pageable pageable = Pageable.ofSize(size); + final Page page = Collections.emptyList().stream() + .collect(PageCollectors.toFilteredSortedPage(pageable, i -> i > 0, Integer::compare)); + + assertEquals(size, page.getSize()); + assertTrue(page.getContent().isEmpty()); + } + + @Test + void secondPage() { + final Pageable pageable = Pageable.ofSize(size / 4).withPage(2); + final Page page = ints.stream() + .collect(PageCollectors.toFilteredSortedPage(pageable, i -> i < 0, Integer::compare)); + + assertEquals(size / 4, page.getSize()); + assertTrue(page.getContent().size() <= size); + + final List content = page.getContent(); + for (final Integer element : content) { + assertTrue(element < 0); + } + + for (int j = 1; j < content.size(); j++) { + assertTrue(Integer.compare(content.get(j - 1), content.get(j)) < 0); + } + } + + @Test + void checkData() { + final List datas = Arrays.asList("un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf", + "dix"); + + final int size = datas.size(); + final Pageable pageable = Pageable.ofSize(size / 2).withPage(0); + final Page page = datas.stream() + .collect(PageCollectors.toFilteredSortedPage(pageable, t -> t.contains("i"), String::compareTo)); + + assertEquals(size / 2, page.getSize()); + assertEquals(size / 2, page.getContent().size()); + for (final String string : page.getContent()) { + assertTrue(string.contains("i")); + assertFalse(!string.contains("i")); + } + assertIterableEquals(page.getContent(), Arrays.asList("cinq", "dix", "huit", "six", "trois")); + } + +} diff --git a/src/test/java/org/springframework/data/util/PageCollectorsToPageTest.java b/src/test/java/org/springframework/data/util/PageCollectorsToPageTest.java new file mode 100644 index 0000000000..915a22fcfb --- /dev/null +++ b/src/test/java/org/springframework/data/util/PageCollectorsToPageTest.java @@ -0,0 +1,72 @@ +package org.springframework.data.util; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +public class PageCollectorsToPageTest { + + private List ints; + private int size; + + @BeforeEach + void init() { + final Random rand = new Random(); + size = rand.nextInt(10000); + ints = IntStream.range(0, size).mapToObj(i -> rand.nextInt()).collect(Collectors.toList()); + } + + @Test + void fullPage() { + final Pageable pageable = Pageable.ofSize(size); + final Page page = ints.stream().collect(PageCollectors.toPage(pageable)); + + assertEquals(size, page.getSize()); + assertEquals(size, page.getContent().size()); + } + + @Test + void emptyPage() { + final Pageable pageable = Pageable.ofSize(size); + final Page page = Collections.emptyList().stream().collect(PageCollectors.toPage(pageable)); + + assertEquals(size, page.getSize()); + assertEquals(0, page.getContent().size()); + } + + @Test + void secondPage() { + final Pageable pageable = Pageable.ofSize(size / 4).withPage(2); + final Page page = ints.stream().collect(PageCollectors.toPage(pageable)); + + assertEquals(size / 4, page.getSize()); + assertEquals(size / 4, page.getContent().size()); + } + + @Test + void checkData() { + final List datas = Arrays.asList("un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf", + "dix"); + + final int size = datas.size(); + final Pageable pageable = Pageable.ofSize(size / 5).withPage(2); + final Page page = datas.stream().collect(PageCollectors.toPage(pageable)); + + assertEquals(size / 4, page.getSize()); + assertEquals(size / 4, page.getContent().size()); + assertEquals("cinq", page.getContent().get(0)); + assertEquals("six", page.getContent().get(1)); + + } + +} diff --git a/src/test/java/org/springframework/data/util/PageCollectorsToSortedPageTest.java b/src/test/java/org/springframework/data/util/PageCollectorsToSortedPageTest.java new file mode 100644 index 0000000000..4d14c02c2b --- /dev/null +++ b/src/test/java/org/springframework/data/util/PageCollectorsToSortedPageTest.java @@ -0,0 +1,82 @@ +package org.springframework.data.util; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertIterableEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +public class PageCollectorsToSortedPageTest { + + private List ints; + private int size; + + @BeforeEach + void init() { + final Random rand = new Random(); + size = rand.nextInt(10000); + ints = IntStream.range(0, size).mapToObj(i -> rand.nextInt()).collect(Collectors.toList()); + } + + @Test + void fullPage() { + final Pageable pageable = Pageable.ofSize(size); + final Page page = ints.stream().collect(PageCollectors.toSortedPage(pageable, Integer::compare)); + + assertEquals(size, page.getSize()); + assertEquals(size, page.getContent().size()); + + final List content = page.getContent(); + for (int i = 1; i < size; i++) { + assertTrue(Integer.compare(content.get(i - 1), content.get(i)) < 0); + } + } + + @Test + void emptyPage() { + final Pageable pageable = Pageable.ofSize(size); + final Page page = Collections.emptyList().stream() + .collect(PageCollectors.toSortedPage(pageable, Integer::compare)); + + assertEquals(size, page.getSize()); + assertTrue(page.getContent().isEmpty()); + } + + @Test + void secondPage() { + final Pageable pageable = Pageable.ofSize(size / 4).withPage(2); + final Page page = ints.stream().collect(PageCollectors.toSortedPage(pageable, Integer::compare)); + + assertEquals(size / 4, page.getSize()); + assertEquals(size / 4, page.getContent().size()); + final List content = page.getContent(); + for (int i = 1; i < content.size(); i++) { + assertTrue(Integer.compare(content.get(i - 1), content.get(i)) < 0); + } + } + + @Test + void checkData() { + final List datas = Arrays.asList("un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf", + "dix"); + + final int size = datas.size(); + final Pageable pageable = Pageable.ofSize(size / 2).withPage(1); + final Page page = datas.stream().collect(PageCollectors.toSortedPage(pageable, String::compareTo)); + + assertEquals(size / 2, page.getSize()); + assertEquals(size / 2, page.getContent().size()); + assertIterableEquals(page.getContent(), Arrays.asList("dix", "huit", "neuf", "sept", "six")); + } + +} From e654ed0c426c7801efa2b8d42930e6ebf0c31d92 Mon Sep 17 00:00:00 2001 From: Zorglube Date: Mon, 25 Oct 2021 18:31:23 +0200 Subject: [PATCH 02/10] Add PageCollectors --- .../data/util/PageCollectors.java | 278 ++++++++++++++++++ .../PageCollectorsToFilteredPageTest.java | 84 ++++++ ...ageCollectorsToFilteredSortedPageTest.java | 99 +++++++ .../data/util/PageCollectorsToPageTest.java | 72 +++++ .../util/PageCollectorsToSortedPageTest.java | 82 ++++++ 5 files changed, 615 insertions(+) create mode 100644 src/main/java/org/springframework/data/util/PageCollectors.java create mode 100644 src/test/java/org/springframework/data/util/PageCollectorsToFilteredPageTest.java create mode 100644 src/test/java/org/springframework/data/util/PageCollectorsToFilteredSortedPageTest.java create mode 100644 src/test/java/org/springframework/data/util/PageCollectorsToPageTest.java create mode 100644 src/test/java/org/springframework/data/util/PageCollectorsToSortedPageTest.java diff --git a/src/main/java/org/springframework/data/util/PageCollectors.java b/src/main/java/org/springframework/data/util/PageCollectors.java new file mode 100644 index 0000000000..2f727c96bb --- /dev/null +++ b/src/main/java/org/springframework/data/util/PageCollectors.java @@ -0,0 +1,278 @@ +package org.springframework.data.util; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.BinaryOperator; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.stream.Collector; +import java.util.stream.Collector.Characteristics; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; + +public final class PageCollectors { + + private static final Set characteristics = Collections.emptySet(); + + /** + * Reduce the {@link Stream} as {@link Page} based on the {@link Pageable} + * information. + * + * @param + * @param p + * @return a {@link Page} containing a subset of the {@link Stream} + */ + public static Collector, Page> toPage(final Pageable p) { + return new PageCollectorImpl<>(p); + } + + private static class PageCollectorImpl implements Collector, Page> { + + Pageable p; + + public PageCollectorImpl(final Pageable p) { + this.p = Objects.requireNonNull(p); + } + + @Override + public Set characteristics() { + return characteristics; + } + + @Override + public Supplier> supplier() { + return ArrayList::new; + } + + @Override + public BiConsumer, T> accumulator() { + return List::add; + } + + @Override + public BinaryOperator> combiner() { + return (left, right) -> { + left.addAll(right); + return left; + }; + } + + @Override + public Function, Page> finisher() { + return t -> { + final int pageNumber = p.getPageNumber(); + final int pageSize = p.getPageSize(); + final int fromIndex = Math.min(t.size(), pageNumber * pageSize); + final int toIndex = Math.min(t.size(), (pageNumber + 1) * pageSize); + + return new PageImpl<>(t.subList(fromIndex, toIndex), p, t.size()); + }; + } + + } + + /** + * Reduce the {@link Stream} as {@link Page} based on the {@link Pageable} + * information. + * + * @param + * @param p + * @return a {@link Page} containing a subset of the {@link Stream} sort + * following the {@link Comparator} + */ + public static Collector, Page> toSortedPage(final Pageable p, final Comparator c) { + return new SortedPageCollectorImpl<>(p, c); + } + + private static class SortedPageCollectorImpl implements Collector, Page> { + + Pageable p; + Comparator c; + + public SortedPageCollectorImpl(final Pageable p, final Comparator c) { + this.p = Objects.requireNonNull(p); + this.c = Objects.requireNonNull(c); + } + + @Override + public Set characteristics() { + return characteristics; + } + + @Override + public Supplier> supplier() { + return ArrayList::new; + } + + @Override + public BiConsumer, T> accumulator() { + return List::add; + } + + @Override + public BinaryOperator> combiner() { + return (left, right) -> { + left.addAll(right); + return left; + }; + } + + @Override + public Function, Page> finisher() { + return t -> { + final int pageNumber = p.getPageNumber(); + final int pageSize = p.getPageSize(); + final int fromIndex = Math.min(t.size(), pageNumber * pageSize); + final int toIndex = Math.min(t.size(), (pageNumber + 1) * pageSize); + + final List data = t.subList(fromIndex, toIndex); + data.sort(c); + + return new PageImpl<>(data, p, t.size()); + }; + } + + } + + /** + * Reduce the {@link Stream} as {@link Page} based on the {@link Pageable} + * information.
+ * + * The {@link Stream} is filtered before subset of data + * isolated + * + * @param + * @param p + * @return a {@link Page} containing a subset of the {@link Stream} + */ + public static Collector, Page> toFilteredPage(final Pageable p, final Predicate f) { + return new FilteredPageCollectorImpl<>(p, f); + } + + private static class FilteredPageCollectorImpl implements Collector, Page> { + + Pageable p; + Predicate f; + + public FilteredPageCollectorImpl(final Pageable p, final Predicate f) { + this.p = Objects.requireNonNull(p); + this.f = Objects.requireNonNull(f); + } + + @Override + public Set characteristics() { + return characteristics; + } + + @Override + public Supplier> supplier() { + return ArrayList::new; + } + + @Override + public BiConsumer, T> accumulator() { + return List::add; + } + + @Override + public BinaryOperator> combiner() { + return (left, right) -> { + left.addAll(right); + return left; + }; + } + + @Override + public Function, Page> finisher() { + return t -> { + final List data = t.stream().filter(f).collect(Collectors.toList()); + + final int pageNumber = p.getPageNumber(); + final int pageSize = p.getPageSize(); + final int fromIndex = Math.min(data.size(), pageNumber * pageSize); + final int toIndex = Math.min(data.size(), (pageNumber + 1) * pageSize); + + return new PageImpl<>(data.subList(fromIndex, toIndex), p, t.size()); + }; + } + + } + + /** + * Reduce the {@link Stream} as {@link Page} based on the {@link Pageable} + * information.
+ * + * The {@link Stream} is filtered then sorted then the subset of data + * isolated + * + * @param + * @param p + * @return a {@link Page} containing a subset of the {@link Stream} + */ + public static Collector, Page> toFilteredSortedPage(final Pageable p, final Predicate f, + final Comparator c) { + return new FilteredSortedPageCollectorImpl<>(p, f, c); + } + + private static class FilteredSortedPageCollectorImpl implements Collector, Page> { + + Pageable p; + Predicate f; + Comparator c; + + public FilteredSortedPageCollectorImpl(final Pageable p, final Predicate f, final Comparator c) { + this.p = Objects.requireNonNull(p); + this.f = Objects.requireNonNull(f); + this.c = Objects.requireNonNull(c); + } + + @Override + public Set characteristics() { + return characteristics; + } + + @Override + public Supplier> supplier() { + return ArrayList::new; + } + + @Override + public BiConsumer, T> accumulator() { + return List::add; + } + + @Override + public BinaryOperator> combiner() { + return (left, right) -> { + left.addAll(right); + return left; + }; + } + + @Override + public Function, Page> finisher() { + return t -> { + final List data = t.stream().filter(f).sorted(c).collect(Collectors.toList()); + + final int pageNumber = p.getPageNumber(); + final int pageSize = p.getPageSize(); + final int fromIndex = Math.min(data.size(), pageNumber * pageSize); + final int toIndex = Math.min(data.size(), (pageNumber + 1) * pageSize); + + return new PageImpl<>(data.subList(fromIndex, toIndex), p, t.size()); + }; + } + + } + +} diff --git a/src/test/java/org/springframework/data/util/PageCollectorsToFilteredPageTest.java b/src/test/java/org/springframework/data/util/PageCollectorsToFilteredPageTest.java new file mode 100644 index 0000000000..e42725d18b --- /dev/null +++ b/src/test/java/org/springframework/data/util/PageCollectorsToFilteredPageTest.java @@ -0,0 +1,84 @@ +package org.springframework.data.util; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertIterableEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +public class PageCollectorsToFilteredPageTest { + + private List ints; + private int size; + + @BeforeEach + void init() { + final Random rand = new Random(); + size = rand.nextInt(10000); + ints = IntStream.range(0, size).mapToObj(i -> rand.nextInt()).collect(Collectors.toList()); + } + + @Test + void fullPage() { + final Pageable pageable = Pageable.ofSize(size); + final Page page = ints.stream().collect(PageCollectors.toFilteredPage(pageable, i -> i > 0)); + + assertEquals(size, page.getSize()); + assertTrue(page.getContent().size() <= size); + for (final Integer element : page.getContent()) { + assertTrue(element > 0); + } + } + + @Test + void emptyPage() { + final Pageable pageable = Pageable.ofSize(size); + final Page page = Collections.emptyList().stream() + .collect(PageCollectors.toFilteredPage(pageable, i -> i > 0)); + + assertEquals(size, page.getSize()); + assertTrue(page.getContent().isEmpty()); + } + + @Test + void secondPage() { + final Pageable pageable = Pageable.ofSize(size / 4).withPage(2); + final Page page = ints.stream().collect(PageCollectors.toFilteredPage(pageable, i -> i < 0)); + + assertEquals(size / 4, page.getSize()); + assertTrue(page.getContent().size() <= size); + for (final Integer element : page.getContent()) { + assertTrue(element < 0); + } + } + + @Test + void checkData() { + final List datas = Arrays.asList("un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf", + "dix"); + + final int size = datas.size(); + final Pageable pageable = Pageable.ofSize(size / 2).withPage(0); + final Page page = datas.stream().collect(PageCollectors.toFilteredPage(pageable, t -> t.contains("i"))); + + assertEquals(size / 2, page.getSize()); + assertEquals(size / 2, page.getContent().size()); + for (final String string : page.getContent()) { + assertTrue(string.contains("i")); + assertFalse(!string.contains("i")); + } + assertIterableEquals(page.getContent(), Arrays.asList("trois", "cinq", "six", "huit", "dix")); + } + +} diff --git a/src/test/java/org/springframework/data/util/PageCollectorsToFilteredSortedPageTest.java b/src/test/java/org/springframework/data/util/PageCollectorsToFilteredSortedPageTest.java new file mode 100644 index 0000000000..77f8312bcb --- /dev/null +++ b/src/test/java/org/springframework/data/util/PageCollectorsToFilteredSortedPageTest.java @@ -0,0 +1,99 @@ +package org.springframework.data.util; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertIterableEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +public class PageCollectorsToFilteredSortedPageTest { + + private List ints; + private int size; + + @BeforeEach + void init() { + final Random rand = new Random(); + size = rand.nextInt(10000); + ints = IntStream.range(0, size).mapToObj(i -> rand.nextInt()).collect(Collectors.toList()); + } + + @Test + void fullPage() { + final Pageable pageable = Pageable.ofSize(size); + final Page page = ints.stream() + .collect(PageCollectors.toFilteredSortedPage(pageable, i -> i > 0, Integer::compare)); + + assertEquals(size, page.getSize()); + assertTrue(page.getContent().size() <= size); + + final List content = page.getContent(); + for (final Integer element : content) { + assertTrue(element > 0); + } + + for (int j = 1; j < content.size(); j++) { + assertTrue(Integer.compare(content.get(j - 1), content.get(j)) < 0); + } + } + + @Test + void emptyPage() { + final Pageable pageable = Pageable.ofSize(size); + final Page page = Collections.emptyList().stream() + .collect(PageCollectors.toFilteredSortedPage(pageable, i -> i > 0, Integer::compare)); + + assertEquals(size, page.getSize()); + assertTrue(page.getContent().isEmpty()); + } + + @Test + void secondPage() { + final Pageable pageable = Pageable.ofSize(size / 4).withPage(2); + final Page page = ints.stream() + .collect(PageCollectors.toFilteredSortedPage(pageable, i -> i < 0, Integer::compare)); + + assertEquals(size / 4, page.getSize()); + assertTrue(page.getContent().size() <= size); + + final List content = page.getContent(); + for (final Integer element : content) { + assertTrue(element < 0); + } + + for (int j = 1; j < content.size(); j++) { + assertTrue(Integer.compare(content.get(j - 1), content.get(j)) < 0); + } + } + + @Test + void checkData() { + final List datas = Arrays.asList("un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf", + "dix"); + + final int size = datas.size(); + final Pageable pageable = Pageable.ofSize(size / 2).withPage(0); + final Page page = datas.stream() + .collect(PageCollectors.toFilteredSortedPage(pageable, t -> t.contains("i"), String::compareTo)); + + assertEquals(size / 2, page.getSize()); + assertEquals(size / 2, page.getContent().size()); + for (final String string : page.getContent()) { + assertTrue(string.contains("i")); + assertFalse(!string.contains("i")); + } + assertIterableEquals(page.getContent(), Arrays.asList("cinq", "dix", "huit", "six", "trois")); + } + +} diff --git a/src/test/java/org/springframework/data/util/PageCollectorsToPageTest.java b/src/test/java/org/springframework/data/util/PageCollectorsToPageTest.java new file mode 100644 index 0000000000..915a22fcfb --- /dev/null +++ b/src/test/java/org/springframework/data/util/PageCollectorsToPageTest.java @@ -0,0 +1,72 @@ +package org.springframework.data.util; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +public class PageCollectorsToPageTest { + + private List ints; + private int size; + + @BeforeEach + void init() { + final Random rand = new Random(); + size = rand.nextInt(10000); + ints = IntStream.range(0, size).mapToObj(i -> rand.nextInt()).collect(Collectors.toList()); + } + + @Test + void fullPage() { + final Pageable pageable = Pageable.ofSize(size); + final Page page = ints.stream().collect(PageCollectors.toPage(pageable)); + + assertEquals(size, page.getSize()); + assertEquals(size, page.getContent().size()); + } + + @Test + void emptyPage() { + final Pageable pageable = Pageable.ofSize(size); + final Page page = Collections.emptyList().stream().collect(PageCollectors.toPage(pageable)); + + assertEquals(size, page.getSize()); + assertEquals(0, page.getContent().size()); + } + + @Test + void secondPage() { + final Pageable pageable = Pageable.ofSize(size / 4).withPage(2); + final Page page = ints.stream().collect(PageCollectors.toPage(pageable)); + + assertEquals(size / 4, page.getSize()); + assertEquals(size / 4, page.getContent().size()); + } + + @Test + void checkData() { + final List datas = Arrays.asList("un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf", + "dix"); + + final int size = datas.size(); + final Pageable pageable = Pageable.ofSize(size / 5).withPage(2); + final Page page = datas.stream().collect(PageCollectors.toPage(pageable)); + + assertEquals(size / 4, page.getSize()); + assertEquals(size / 4, page.getContent().size()); + assertEquals("cinq", page.getContent().get(0)); + assertEquals("six", page.getContent().get(1)); + + } + +} diff --git a/src/test/java/org/springframework/data/util/PageCollectorsToSortedPageTest.java b/src/test/java/org/springframework/data/util/PageCollectorsToSortedPageTest.java new file mode 100644 index 0000000000..4d14c02c2b --- /dev/null +++ b/src/test/java/org/springframework/data/util/PageCollectorsToSortedPageTest.java @@ -0,0 +1,82 @@ +package org.springframework.data.util; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertIterableEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +public class PageCollectorsToSortedPageTest { + + private List ints; + private int size; + + @BeforeEach + void init() { + final Random rand = new Random(); + size = rand.nextInt(10000); + ints = IntStream.range(0, size).mapToObj(i -> rand.nextInt()).collect(Collectors.toList()); + } + + @Test + void fullPage() { + final Pageable pageable = Pageable.ofSize(size); + final Page page = ints.stream().collect(PageCollectors.toSortedPage(pageable, Integer::compare)); + + assertEquals(size, page.getSize()); + assertEquals(size, page.getContent().size()); + + final List content = page.getContent(); + for (int i = 1; i < size; i++) { + assertTrue(Integer.compare(content.get(i - 1), content.get(i)) < 0); + } + } + + @Test + void emptyPage() { + final Pageable pageable = Pageable.ofSize(size); + final Page page = Collections.emptyList().stream() + .collect(PageCollectors.toSortedPage(pageable, Integer::compare)); + + assertEquals(size, page.getSize()); + assertTrue(page.getContent().isEmpty()); + } + + @Test + void secondPage() { + final Pageable pageable = Pageable.ofSize(size / 4).withPage(2); + final Page page = ints.stream().collect(PageCollectors.toSortedPage(pageable, Integer::compare)); + + assertEquals(size / 4, page.getSize()); + assertEquals(size / 4, page.getContent().size()); + final List content = page.getContent(); + for (int i = 1; i < content.size(); i++) { + assertTrue(Integer.compare(content.get(i - 1), content.get(i)) < 0); + } + } + + @Test + void checkData() { + final List datas = Arrays.asList("un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf", + "dix"); + + final int size = datas.size(); + final Pageable pageable = Pageable.ofSize(size / 2).withPage(1); + final Page page = datas.stream().collect(PageCollectors.toSortedPage(pageable, String::compareTo)); + + assertEquals(size / 2, page.getSize()); + assertEquals(size / 2, page.getContent().size()); + assertIterableEquals(page.getContent(), Arrays.asList("dix", "huit", "neuf", "sept", "six")); + } + +} From 6d4bd38d7c6a242440934366112c0345423ee34b Mon Sep 17 00:00:00 2001 From: Zorglube Date: Tue, 26 Oct 2021 11:16:58 +0200 Subject: [PATCH 03/10] Rename and add `toSimplePage` Signed-off-by: Zorglube --- .../data/util/PageCollectors.java | 47 ++++++++++++++ .../util/PageCollectorToSimplePageTest.java | 63 +++++++++++++++++++ .../PageCollectorsToFilteredPageTest.java | 5 ++ ...ageCollectorsToFilteredSortedPageTest.java | 5 ++ .../data/util/PageCollectorsToPageTest.java | 5 ++ .../util/PageCollectorsToSortedPageTest.java | 5 ++ 6 files changed, 130 insertions(+) create mode 100644 src/test/java/org/springframework/data/util/PageCollectorToSimplePageTest.java diff --git a/src/main/java/org/springframework/data/util/PageCollectors.java b/src/main/java/org/springframework/data/util/PageCollectors.java index 2f727c96bb..074a3acdc3 100644 --- a/src/main/java/org/springframework/data/util/PageCollectors.java +++ b/src/main/java/org/springframework/data/util/PageCollectors.java @@ -20,10 +20,57 @@ import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; +/** + * Utility methods to work with {@link Page}s. + * + * @author Bertrand Moreau + */ public final class PageCollectors { private static final Set characteristics = Collections.emptySet(); + /** + * Simply put all the {@link Stream} data into a {@link Page}. + * + * @param + * @return a {@link Page} containing all the {@link Stream} datas + */ + public static Collector, Page> toSimplePage() { + return new SimplePageCollectorImpl<>(); + } + + private static class SimplePageCollectorImpl implements Collector, Page> { + + @Override + public Set characteristics() { + return characteristics; + } + + @Override + public Supplier> supplier() { + return ArrayList::new; + } + + @Override + public BiConsumer, T> accumulator() { + return List::add; + } + + @Override + public BinaryOperator> combiner() { + return (left, right) -> { + left.addAll(right); + return left; + }; + } + + @Override + public Function, Page> finisher() { + return PageImpl::new; + } + + } + /** * Reduce the {@link Stream} as {@link Page} based on the {@link Pageable} * information. diff --git a/src/test/java/org/springframework/data/util/PageCollectorToSimplePageTest.java b/src/test/java/org/springframework/data/util/PageCollectorToSimplePageTest.java new file mode 100644 index 0000000000..e87bbd7fd8 --- /dev/null +++ b/src/test/java/org/springframework/data/util/PageCollectorToSimplePageTest.java @@ -0,0 +1,63 @@ +package org.springframework.data.util; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.data.domain.Page; + +/** + * Test methods for {@link PageCollectors}s. + * + * @author Bertrand Moreau + */ +public class PageCollectorToSimplePageTest { + + private List ints; + private int size; + + @BeforeEach + void init() { + final Random rand = new Random(); + size = rand.nextInt(10000); + ints = IntStream.range(0, size).mapToObj(i -> rand.nextInt()).collect(Collectors.toList()); + } + + @Test + void fullPage() { + final Page page = ints.stream().collect(PageCollectors.toSimplePage()); + + assertEquals(size, page.getSize()); + assertEquals(size, page.getContent().size()); + } + + @Test + void emptyPage() { + final Page page = Collections.emptyList().stream().collect(PageCollectors.toSimplePage()); + + assertEquals(0, page.getSize()); + assertEquals(0, page.getContent().size()); + } + + @Test + void checkData() { + final List datas = Arrays.asList("un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf", + "dix"); + + final int size = datas.size(); + final Page page = datas.stream().collect(PageCollectors.toSimplePage()); + + assertEquals(size, page.getSize()); + assertEquals(size, page.getContent().size()); + assertArrayEquals(datas.toArray(), page.getContent().toArray()); + } + +} diff --git a/src/test/java/org/springframework/data/util/PageCollectorsToFilteredPageTest.java b/src/test/java/org/springframework/data/util/PageCollectorsToFilteredPageTest.java index e42725d18b..89b0d7aa95 100644 --- a/src/test/java/org/springframework/data/util/PageCollectorsToFilteredPageTest.java +++ b/src/test/java/org/springframework/data/util/PageCollectorsToFilteredPageTest.java @@ -17,6 +17,11 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +/** + * Test methods for {@link PageCollectors}s. + * + * @author Bertrand Moreau + */ public class PageCollectorsToFilteredPageTest { private List ints; diff --git a/src/test/java/org/springframework/data/util/PageCollectorsToFilteredSortedPageTest.java b/src/test/java/org/springframework/data/util/PageCollectorsToFilteredSortedPageTest.java index 77f8312bcb..deff61ee39 100644 --- a/src/test/java/org/springframework/data/util/PageCollectorsToFilteredSortedPageTest.java +++ b/src/test/java/org/springframework/data/util/PageCollectorsToFilteredSortedPageTest.java @@ -17,6 +17,11 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +/** + * Test methods for {@link PageCollectors}s. + * + * @author Bertrand Moreau + */ public class PageCollectorsToFilteredSortedPageTest { private List ints; diff --git a/src/test/java/org/springframework/data/util/PageCollectorsToPageTest.java b/src/test/java/org/springframework/data/util/PageCollectorsToPageTest.java index 915a22fcfb..d4ae5191b8 100644 --- a/src/test/java/org/springframework/data/util/PageCollectorsToPageTest.java +++ b/src/test/java/org/springframework/data/util/PageCollectorsToPageTest.java @@ -14,6 +14,11 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +/** + * Test methods for {@link PageCollectors}s. + * + * @author Bertrand Moreau + */ public class PageCollectorsToPageTest { private List ints; diff --git a/src/test/java/org/springframework/data/util/PageCollectorsToSortedPageTest.java b/src/test/java/org/springframework/data/util/PageCollectorsToSortedPageTest.java index 4d14c02c2b..cf78af04e2 100644 --- a/src/test/java/org/springframework/data/util/PageCollectorsToSortedPageTest.java +++ b/src/test/java/org/springframework/data/util/PageCollectorsToSortedPageTest.java @@ -16,6 +16,11 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +/** + * Test methods for {@link PageCollectors}s. + * + * @author Bertrand Moreau + */ public class PageCollectorsToSortedPageTest { private List ints; From 1c51eebd11d18927e31d7372b142269302e79091 Mon Sep 17 00:00:00 2001 From: Zorglube Date: Tue, 26 Oct 2021 11:32:07 +0200 Subject: [PATCH 04/10] Formatter Signed-off-by: Zorglube --- .../data/util/PageCollectors.java | 23 ++++++------------- .../PageCollectorsToFilteredPageTest.java | 2 +- ...ageCollectorsToFilteredSortedPageTest.java | 2 +- .../util/PageCollectorsToSortedPageTest.java | 2 +- 4 files changed, 10 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/springframework/data/util/PageCollectors.java b/src/main/java/org/springframework/data/util/PageCollectors.java index 074a3acdc3..15fe4dee27 100644 --- a/src/main/java/org/springframework/data/util/PageCollectors.java +++ b/src/main/java/org/springframework/data/util/PageCollectors.java @@ -72,8 +72,7 @@ public Function, Page> finisher() { } /** - * Reduce the {@link Stream} as {@link Page} based on the {@link Pageable} - * information. + * Reduce the {@link Stream} as {@link Page} based on the {@link Pageable} information. * * @param * @param p @@ -129,13 +128,11 @@ public Function, Page> finisher() { } /** - * Reduce the {@link Stream} as {@link Page} based on the {@link Pageable} - * information. + * Reduce the {@link Stream} as {@link Page} based on the {@link Pageable} information. * * @param * @param p - * @return a {@link Page} containing a subset of the {@link Stream} sort - * following the {@link Comparator} + * @return a {@link Page} containing a subset of the {@link Stream} sort following the {@link Comparator} */ public static Collector, Page> toSortedPage(final Pageable p, final Comparator c) { return new SortedPageCollectorImpl<>(p, c); @@ -192,11 +189,8 @@ public Function, Page> finisher() { } /** - * Reduce the {@link Stream} as {@link Page} based on the {@link Pageable} - * information.
- * - * The {@link Stream} is filtered before subset of data - * isolated + * Reduce the {@link Stream} as {@link Page} based on the {@link Pageable} information.
+ * The {@link Stream} is filtered before subset of data isolated * * @param * @param p @@ -256,11 +250,8 @@ public Function, Page> finisher() { } /** - * Reduce the {@link Stream} as {@link Page} based on the {@link Pageable} - * information.
- * - * The {@link Stream} is filtered then sorted then the subset of data - * isolated + * Reduce the {@link Stream} as {@link Page} based on the {@link Pageable} information.
+ * The {@link Stream} is filtered then sorted then the subset of data isolated * * @param * @param p diff --git a/src/test/java/org/springframework/data/util/PageCollectorsToFilteredPageTest.java b/src/test/java/org/springframework/data/util/PageCollectorsToFilteredPageTest.java index 89b0d7aa95..1271ecfccb 100644 --- a/src/test/java/org/springframework/data/util/PageCollectorsToFilteredPageTest.java +++ b/src/test/java/org/springframework/data/util/PageCollectorsToFilteredPageTest.java @@ -49,7 +49,7 @@ void fullPage() { @Test void emptyPage() { final Pageable pageable = Pageable.ofSize(size); - final Page page = Collections.emptyList().stream() + final Page page = Collections. emptyList().stream() .collect(PageCollectors.toFilteredPage(pageable, i -> i > 0)); assertEquals(size, page.getSize()); diff --git a/src/test/java/org/springframework/data/util/PageCollectorsToFilteredSortedPageTest.java b/src/test/java/org/springframework/data/util/PageCollectorsToFilteredSortedPageTest.java index deff61ee39..f1fa014358 100644 --- a/src/test/java/org/springframework/data/util/PageCollectorsToFilteredSortedPageTest.java +++ b/src/test/java/org/springframework/data/util/PageCollectorsToFilteredSortedPageTest.java @@ -56,7 +56,7 @@ void fullPage() { @Test void emptyPage() { final Pageable pageable = Pageable.ofSize(size); - final Page page = Collections.emptyList().stream() + final Page page = Collections. emptyList().stream() .collect(PageCollectors.toFilteredSortedPage(pageable, i -> i > 0, Integer::compare)); assertEquals(size, page.getSize()); diff --git a/src/test/java/org/springframework/data/util/PageCollectorsToSortedPageTest.java b/src/test/java/org/springframework/data/util/PageCollectorsToSortedPageTest.java index cf78af04e2..bca73737dc 100644 --- a/src/test/java/org/springframework/data/util/PageCollectorsToSortedPageTest.java +++ b/src/test/java/org/springframework/data/util/PageCollectorsToSortedPageTest.java @@ -50,7 +50,7 @@ void fullPage() { @Test void emptyPage() { final Pageable pageable = Pageable.ofSize(size); - final Page page = Collections.emptyList().stream() + final Page page = Collections. emptyList().stream() .collect(PageCollectors.toSortedPage(pageable, Integer::compare)); assertEquals(size, page.getSize()); From 5a25dff956187b041735da64248b63767b708ccf Mon Sep 17 00:00:00 2001 From: Zorglube Date: Tue, 26 Oct 2021 11:56:10 +0200 Subject: [PATCH 05/10] Improve javadoc Signed-off-by: Zorglube --- .../data/util/PageCollectors.java | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/util/PageCollectors.java b/src/main/java/org/springframework/data/util/PageCollectors.java index 15fe4dee27..f89050806c 100644 --- a/src/main/java/org/springframework/data/util/PageCollectors.java +++ b/src/main/java/org/springframework/data/util/PageCollectors.java @@ -21,7 +21,35 @@ import org.springframework.data.domain.Pageable; /** - * Utility methods to work with {@link Page}s. + * Utility methods to work with {@link Stream} and {@link Page}s.
+ * It has been thought to provide some writing like that:
+ *
+ * + * class DatasProvider {
+ * public Page getDatasPage() {
+ * Collection items = [FILL THE ITEMS];
+ * return items.stream().map(...).filter(...).collector(PageCollectors.toSimplePage());
+ * }
+ * }
+ *

+ * or
+ * + * class DatasProvider {
+ * public Page getDatasPage() {
+ * Page page = repo.[ANY PAGED SEARCH];
+ * return page.stream().map(...).filter(...).collector(PageCollectors.toSimplePage());
+ * }
+ * }
+ *

+ * or
+ * + * class DatasProvider {
+ * public Page getDatasPage(Pageable pageable) {
+ * Collection items = [FILL THE ITEMS];
+ * return items.stream().map(...).filter(...).collector(PageCollectors.toPage(pageable));
+ * }
+ * }
+ *
* * @author Bertrand Moreau */ From 89f53fcf63a2f34a5f2dfbfa7e0c5498c3e6b8bb Mon Sep 17 00:00:00 2001 From: Zorglube Date: Tue, 26 Oct 2021 15:04:29 +0200 Subject: [PATCH 06/10] Factorized, use Stream. Signed-off-by: Zorglube --- .../data/util/PageCollectors.java | 26 +++++-------------- .../util/PageCollectorToSimplePageTest.java | 2 +- .../PageCollectorsToFilteredPageTest.java | 2 +- ...ageCollectorsToFilteredSortedPageTest.java | 2 +- .../data/util/PageCollectorsToPageTest.java | 2 +- .../util/PageCollectorsToSortedPageTest.java | 2 +- 6 files changed, 11 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/springframework/data/util/PageCollectors.java b/src/main/java/org/springframework/data/util/PageCollectors.java index f89050806c..f30708bb0a 100644 --- a/src/main/java/org/springframework/data/util/PageCollectors.java +++ b/src/main/java/org/springframework/data/util/PageCollectors.java @@ -1,6 +1,7 @@ package org.springframework.data.util; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -86,10 +87,7 @@ public BiConsumer, T> accumulator() { @Override public BinaryOperator> combiner() { - return (left, right) -> { - left.addAll(right); - return left; - }; + return (left, right) -> Stream.of(left, right).flatMap(Collection::stream).collect(Collectors.toList()); } @Override @@ -135,10 +133,7 @@ public BiConsumer, T> accumulator() { @Override public BinaryOperator> combiner() { - return (left, right) -> { - left.addAll(right); - return left; - }; + return (left, right) -> Stream.of(left, right).flatMap(Collection::stream).collect(Collectors.toList()); } @Override @@ -193,10 +188,7 @@ public BiConsumer, T> accumulator() { @Override public BinaryOperator> combiner() { - return (left, right) -> { - left.addAll(right); - return left; - }; + return (left, right) -> Stream.of(left, right).flatMap(Collection::stream).collect(Collectors.toList()); } @Override @@ -255,10 +247,7 @@ public BiConsumer, T> accumulator() { @Override public BinaryOperator> combiner() { - return (left, right) -> { - left.addAll(right); - return left; - }; + return (left, right) -> Stream.of(left, right).flatMap(Collection::stream).collect(Collectors.toList()); } @Override @@ -319,10 +308,7 @@ public BiConsumer, T> accumulator() { @Override public BinaryOperator> combiner() { - return (left, right) -> { - left.addAll(right); - return left; - }; + return (left, right) -> Stream.of(left, right).flatMap(Collection::stream).collect(Collectors.toList()); } @Override diff --git a/src/test/java/org/springframework/data/util/PageCollectorToSimplePageTest.java b/src/test/java/org/springframework/data/util/PageCollectorToSimplePageTest.java index e87bbd7fd8..d14609178a 100644 --- a/src/test/java/org/springframework/data/util/PageCollectorToSimplePageTest.java +++ b/src/test/java/org/springframework/data/util/PageCollectorToSimplePageTest.java @@ -15,7 +15,7 @@ import org.springframework.data.domain.Page; /** - * Test methods for {@link PageCollectors}s. + * Test methods for {@link PageCollectors}. * * @author Bertrand Moreau */ diff --git a/src/test/java/org/springframework/data/util/PageCollectorsToFilteredPageTest.java b/src/test/java/org/springframework/data/util/PageCollectorsToFilteredPageTest.java index 1271ecfccb..6b95965a3c 100644 --- a/src/test/java/org/springframework/data/util/PageCollectorsToFilteredPageTest.java +++ b/src/test/java/org/springframework/data/util/PageCollectorsToFilteredPageTest.java @@ -18,7 +18,7 @@ import org.springframework.data.domain.Pageable; /** - * Test methods for {@link PageCollectors}s. + * Test methods for {@link PageCollectors}. * * @author Bertrand Moreau */ diff --git a/src/test/java/org/springframework/data/util/PageCollectorsToFilteredSortedPageTest.java b/src/test/java/org/springframework/data/util/PageCollectorsToFilteredSortedPageTest.java index f1fa014358..085e61dabe 100644 --- a/src/test/java/org/springframework/data/util/PageCollectorsToFilteredSortedPageTest.java +++ b/src/test/java/org/springframework/data/util/PageCollectorsToFilteredSortedPageTest.java @@ -18,7 +18,7 @@ import org.springframework.data.domain.Pageable; /** - * Test methods for {@link PageCollectors}s. + * Test methods for {@link PageCollectors}. * * @author Bertrand Moreau */ diff --git a/src/test/java/org/springframework/data/util/PageCollectorsToPageTest.java b/src/test/java/org/springframework/data/util/PageCollectorsToPageTest.java index d4ae5191b8..638e4f9b9e 100644 --- a/src/test/java/org/springframework/data/util/PageCollectorsToPageTest.java +++ b/src/test/java/org/springframework/data/util/PageCollectorsToPageTest.java @@ -15,7 +15,7 @@ import org.springframework.data.domain.Pageable; /** - * Test methods for {@link PageCollectors}s. + * Test methods for {@link PageCollectors}. * * @author Bertrand Moreau */ diff --git a/src/test/java/org/springframework/data/util/PageCollectorsToSortedPageTest.java b/src/test/java/org/springframework/data/util/PageCollectorsToSortedPageTest.java index bca73737dc..49b5f78262 100644 --- a/src/test/java/org/springframework/data/util/PageCollectorsToSortedPageTest.java +++ b/src/test/java/org/springframework/data/util/PageCollectorsToSortedPageTest.java @@ -17,7 +17,7 @@ import org.springframework.data.domain.Pageable; /** - * Test methods for {@link PageCollectors}s. + * Test methods for {@link PageCollectors}. * * @author Bertrand Moreau */ From 7b9bf41ad9bcd52c0d70b3e0721a2fa84163ae8a Mon Sep 17 00:00:00 2001 From: Zorglube Date: Tue, 26 Oct 2021 16:14:03 +0200 Subject: [PATCH 07/10] add toSimplePage(Pageable p) Signed-off-by: Zorglube --- .../data/util/PageCollectors.java | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/util/PageCollectors.java b/src/main/java/org/springframework/data/util/PageCollectors.java index f30708bb0a..e607004e02 100644 --- a/src/main/java/org/springframework/data/util/PageCollectors.java +++ b/src/main/java/org/springframework/data/util/PageCollectors.java @@ -58,6 +58,17 @@ public final class PageCollectors { private static final Set characteristics = Collections.emptySet(); + /** + * Simply put all the {@link Stream} data into a {@link Page}. + * + * @param p + * @param + * @return a {@link Page} containing all the {@link Stream} data and the {@link Pageable} informations. + */ + public static Collector, Page> toSimplePage(final Pageable p) { + return new SimplePageCollectorImpl<>(p); + } + /** * Simply put all the {@link Stream} data into a {@link Page}. * @@ -70,6 +81,14 @@ public static Collector, Page> toSimplePage() { private static class SimplePageCollectorImpl implements Collector, Page> { + private Pageable p = null; + + public SimplePageCollectorImpl() {} + + public SimplePageCollectorImpl(final Pageable p) { + this.p = Objects.requireNonNull(p); + } + @Override public Set characteristics() { return characteristics; @@ -92,7 +111,7 @@ public BinaryOperator> combiner() { @Override public Function, Page> finisher() { - return PageImpl::new; + return t -> p == null ? new PageImpl<>(t) : new PageImpl<>(t, p, t.size()); } } From ca0ad3318a7670832d80c437669578784fe54162 Mon Sep 17 00:00:00 2001 From: Zorglube Date: Tue, 26 Oct 2021 17:01:11 +0200 Subject: [PATCH 08/10] Formating Signed-off-by: Zorglube --- .../java/org/springframework/data/util/PageCollectors.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/util/PageCollectors.java b/src/main/java/org/springframework/data/util/PageCollectors.java index e607004e02..a2e96b50e3 100644 --- a/src/main/java/org/springframework/data/util/PageCollectors.java +++ b/src/main/java/org/springframework/data/util/PageCollectors.java @@ -59,7 +59,8 @@ public final class PageCollectors { private static final Set characteristics = Collections.emptySet(); /** - * Simply put all the {@link Stream} data into a {@link Page}. + * Simply put all the {@link Stream} data into a {@link Page}.Use is IF the {@link Page} is already returned + * by the repo BUT processed after * * @param p * @param From d72a31a5c83a1d0cb942114fa1b80f1bca982476 Mon Sep 17 00:00:00 2001 From: Zorglube Date: Tue, 26 Oct 2021 17:09:15 +0200 Subject: [PATCH 09/10] Complete Unit Testing Signed-off-by: Zorglube --- .../data/util/PageCollectorToSimplePageTest.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/test/java/org/springframework/data/util/PageCollectorToSimplePageTest.java b/src/test/java/org/springframework/data/util/PageCollectorToSimplePageTest.java index d14609178a..76d0ad6b0a 100644 --- a/src/test/java/org/springframework/data/util/PageCollectorToSimplePageTest.java +++ b/src/test/java/org/springframework/data/util/PageCollectorToSimplePageTest.java @@ -13,6 +13,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; /** * Test methods for {@link PageCollectors}. @@ -37,6 +38,17 @@ void fullPage() { assertEquals(size, page.getSize()); assertEquals(size, page.getContent().size()); + assertEquals(0, page.getNumber()); + } + + @Test + void fullPageWithPageable() { + final Pageable p = Pageable.ofSize(size).withPage(3); + final Page page = ints.stream().collect(PageCollectors.toSimplePage(p)); + + assertEquals(size, page.getSize()); + assertEquals(size, page.getContent().size()); + assertEquals(3, page.getNumber()); } @Test @@ -45,6 +57,7 @@ void emptyPage() { assertEquals(0, page.getSize()); assertEquals(0, page.getContent().size()); + assertEquals(0, page.getNumber()); } @Test @@ -58,6 +71,7 @@ void checkData() { assertEquals(size, page.getSize()); assertEquals(size, page.getContent().size()); assertArrayEquals(datas.toArray(), page.getContent().toArray()); + assertEquals(0, page.getNumber()); } } From aabad920cf8e5d10b185f00faa2bd29689c41191 Mon Sep 17 00:00:00 2001 From: Zorglube Date: Tue, 26 Oct 2021 17:32:51 +0200 Subject: [PATCH 10/10] Vars visibility Signed-off-by: Zorglube --- .../data/util/PageCollectors.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/springframework/data/util/PageCollectors.java b/src/main/java/org/springframework/data/util/PageCollectors.java index a2e96b50e3..7cfc6ffb14 100644 --- a/src/main/java/org/springframework/data/util/PageCollectors.java +++ b/src/main/java/org/springframework/data/util/PageCollectors.java @@ -130,7 +130,7 @@ public static Collector, Page> toPage(final Pageable p) { private static class PageCollectorImpl implements Collector, Page> { - Pageable p; + private final Pageable p; public PageCollectorImpl(final Pageable p) { this.p = Objects.requireNonNull(p); @@ -183,8 +183,8 @@ public static Collector, Page> toSortedPage(final Pageable p, private static class SortedPageCollectorImpl implements Collector, Page> { - Pageable p; - Comparator c; + private final Pageable p; + private final Comparator c; public SortedPageCollectorImpl(final Pageable p, final Comparator c) { this.p = Objects.requireNonNull(p); @@ -242,8 +242,8 @@ public static Collector, Page> toFilteredPage(final Pageable p private static class FilteredPageCollectorImpl implements Collector, Page> { - Pageable p; - Predicate f; + private final Pageable p; + private final Predicate f; public FilteredPageCollectorImpl(final Pageable p, final Predicate f) { this.p = Objects.requireNonNull(p); @@ -301,9 +301,9 @@ public static Collector, Page> toFilteredSortedPage(final Page private static class FilteredSortedPageCollectorImpl implements Collector, Page> { - Pageable p; - Predicate f; - Comparator c; + private final Pageable p; + private final Predicate f; + private final Comparator c; public FilteredSortedPageCollectorImpl(final Pageable p, final Predicate f, final Comparator c) { this.p = Objects.requireNonNull(p);