This commit is contained in:
Looly 2023-03-15 03:07:19 +08:00
parent b2235e4520
commit 48fdda9faf
16 changed files with 520 additions and 462 deletions

View File

@ -1735,21 +1735,7 @@ public class CollUtil {
list.sort(comparator);
}
return page(pageNo, pageSize, list);
}
/**
* 对指定List分页取值
*
* @param <T> 集合元素类型
* @param pageNo 页码从0开始计数0表示第一页
* @param pageSize 每页的条目数
* @param list 列表
* @return 分页后的段落内容
* @since 4.1.20
*/
public static <T> List<T> page(final int pageNo, final int pageSize, final List<T> list) {
return ListUtil.page(pageNo, pageSize, list);
return ListUtil.page(list, pageNo, pageSize);
}
/**

View File

@ -8,20 +8,11 @@ import cn.hutool.core.collection.partition.RandomAccessPartition;
import cn.hutool.core.comparator.PinyinComparator;
import cn.hutool.core.comparator.PropertyComparator;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.math.PageInfo;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.PageUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.RandomAccess;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Consumer;
import java.util.function.Predicate;
@ -254,42 +245,53 @@ public class ListUtil {
* 对指定List分页取值
*
* @param <T> 集合元素类型
* @param pageNo 页码第一页的页码取决于{@link PageUtil#getFirstPageNo()}默认0
* @param pageNo 页码第一页的页码从0开始
* @param pageSize 每页的条目数
* @param list 列表
* @return 分页后的段落内容
* @since 4.1.20
*/
public static <T> List<T> page(final int pageNo, final int pageSize, final List<T> list) {
public static <T> List<T> page(final List<T> list, final int pageNo, final int pageSize) {
if (CollUtil.isEmpty(list)) {
return new ArrayList<>(0);
}
return page(list, PageInfo.of(list.size(), pageSize)
.setFirstPageNo(0).setPageNo(pageNo));
}
/**
* 对指定List分页取值
*
* @param <T> 集合元素类型
* @param pageInfo 分页信息
* @param list 列表
* @return 分页后的段落内容
* @since 4.1.20
*/
public static <T> List<T> page(final List<T> list, final PageInfo pageInfo) {
if (CollUtil.isEmpty(list)) {
return new ArrayList<>(0);
}
final int resultSize = list.size();
// 每页条目数大于总数直接返回所有
if (resultSize <= pageSize) {
if (pageNo < (PageUtil.getFirstPageNo() + 1)) {
final int total = list.size();
final int pageSize = pageInfo.getPageSize();
// 不满一页
if (total <= pageSize) {
if (pageInfo.isFirstPage()) {
// 页码为1返回所有
return view(list);
} else {
// 越界直接返回空
return new ArrayList<>(0);
}
}
// 相乘可能会导致越界 临时用long
if (((long) (pageNo - PageUtil.getFirstPageNo()) * pageSize) > resultSize) {
if (pageInfo.getBeginIndex() > total) {
// 越界直接返回空
return new ArrayList<>(0);
}
final int[] startEnd = PageUtil.transToStartEnd(pageNo, pageSize);
if (startEnd[1] > resultSize) {
startEnd[1] = resultSize;
if (startEnd[0] > startEnd[1]) {
return new ArrayList<>(0);
}
}
return sub(list, startEnd[0], startEnd[1]);
return sub(list, pageInfo.getBeginIndex(), pageInfo.getEndIndexExclude());
}
/**
@ -307,16 +309,11 @@ public class ListUtil {
}
final int total = list.size();
final int totalPage = PageUtil.totalPage(total, pageSize);
for (int pageNo = PageUtil.getFirstPageNo(); pageNo < totalPage + PageUtil.getFirstPageNo(); pageNo++) {
// 获取当前页在列表中对应的起止序号
final int[] startEnd = PageUtil.transToStartEnd(pageNo, pageSize);
if (startEnd[1] > total) {
startEnd[1] = total;
}
final PageInfo pageInfo = PageInfo.of(total, pageSize);
while(pageInfo.isValidPage()){
// 返回数据
pageListConsumer.accept(sub(list, startEnd[0], startEnd[1]));
pageListConsumer.accept(sub(list, pageInfo.getBeginIndex(), pageInfo.getEndIndexExclude()));
pageInfo.nextPage();
}
}
@ -346,7 +343,7 @@ public class ListUtil {
if (CollUtil.isEmpty(list)) {
return list;
}
if(null == c){
if (null == c) {
c = Comparator.nullsFirst((Comparator<? super T>) Comparator.naturalOrder());
}
list.sort(c);
@ -446,10 +443,10 @@ public class ListUtil {
/**
* 在指定位置设置元素当index小于List的长度时替换指定位置的值否则追加{@code paddingElement}直到到达index后设置值
*
* @param <T> 元素类型
* @param list List列表
* @param index 位置
* @param element 新元素
* @param <T> 元素类型
* @param list List列表
* @param index 位置
* @param element 新元素
* @param paddingElement 填充的值
* @return 原List
* @since 5.8.4
@ -471,29 +468,29 @@ public class ListUtil {
/**
* 截取集合的部分
*
* @param <T> 集合元素类型
* @param list 被截取的数组
* @param start 开始位置包含
* @param end 结束位置不包含
* @param <T> 集合元素类型
* @param list 被截取的数组
* @param begionInclude 开始位置包含
* @param endExclude 结束位置不包含
* @return 截取后的数组当开始位置超过最大时返回空的List
*/
public static <T> List<T> sub(final List<T> list, final int start, final int end) {
return sub(list, start, end, 1);
public static <T> List<T> sub(final List<T> list, final int begionInclude, final int endExclude) {
return sub(list, begionInclude, endExclude, 1);
}
/**
* 截取集合的部分<br>
* 此方法与{@link List#subList(int, int)} 不同在于子列表是新的副本操作子列表不会影响原列表
*
* @param <T> 集合元素类型
* @param list 被截取的数组
* @param start 开始位置包含
* @param end 结束位置不包含
* @param step 步进
* @param <T> 集合元素类型
* @param list 被截取的数组
* @param begionInclude 开始位置包含
* @param endExclude 结束位置不包含
* @param step 步进
* @return 截取后的数组当开始位置超过最大时返回空的List
* @since 4.0.6
*/
public static <T> List<T> sub(final List<T> list, int start, int end, int step) {
public static <T> List<T> sub(final List<T> list, int begionInclude, int endExclude, int step) {
if (list == null) {
return null;
}
@ -503,25 +500,25 @@ public class ListUtil {
}
final int size = list.size();
if (start < 0) {
start += size;
if (begionInclude < 0) {
begionInclude += size;
}
if (end < 0) {
end += size;
if (endExclude < 0) {
endExclude += size;
}
if (start == size) {
if (begionInclude == size) {
return new ArrayList<>(0);
}
if (start > end) {
final int tmp = start;
start = end;
end = tmp;
if (begionInclude > endExclude) {
final int tmp = begionInclude;
begionInclude = endExclude;
endExclude = tmp;
}
if (end > size) {
if (start >= size) {
if (endExclude > size) {
if (begionInclude >= size) {
return new ArrayList<>(0);
}
end = size;
endExclude = size;
}
if (step < 1) {
@ -529,7 +526,7 @@ public class ListUtil {
}
final List<T> result = new ArrayList<>();
for (int i = start; i < end; i += step) {
for (int i = begionInclude; i < endExclude; i += step) {
result.add(list.get(i));
}
return result;
@ -719,8 +716,8 @@ public class ListUtil {
* 通过删除或替换现有元素或者原地添加新的元素来修改列表并以列表形式返回被修改的内容此方法不会改变原列表
* 类似js的<a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/splice">splice</a>函数
*
* @param <T> 元素类型
* @param list 列表
* @param <T> 元素类型
* @param list 列表
* @param start 指定修改的开始位置 0 计数, 可以为负数, -1代表最后一个元素
* @param deleteCount 删除个数必须是正整数
* @param items 放入的元素

View File

@ -1,5 +1,7 @@
package cn.hutool.core.lang;
import cn.hutool.core.text.StrUtil;
/**
* 片段默认实现
*
@ -9,26 +11,32 @@ package cn.hutool.core.lang;
*/
public class DefaultSegment<T extends Number> implements Segment<T> {
protected T startIndex;
protected T beginIndex;
protected T endIndex;
/**
* 构造
* @param startIndex 起始位置
* @param endIndex 结束位置
*
* @param beginIndex 起始位置
* @param endIndex 结束位置
*/
public DefaultSegment(final T startIndex, final T endIndex) {
this.startIndex = startIndex;
public DefaultSegment(final T beginIndex, final T endIndex) {
this.beginIndex = beginIndex;
this.endIndex = endIndex;
}
@Override
public T getStartIndex() {
return this.startIndex;
public T getBeginIndex() {
return this.beginIndex;
}
@Override
public T getEndIndex() {
return this.endIndex;
}
@Override
public String toString() {
return StrUtil.format("[{}, {}]", beginIndex, endIndex);
}
}

View File

@ -19,7 +19,7 @@ public interface Segment<T extends Number> {
*
* @return 起始位置
*/
T getStartIndex();
T getBeginIndex();
/**
* 获取结束位置
@ -34,7 +34,7 @@ public interface Segment<T extends Number> {
* @return 片段长度
*/
default T length(){
final T start = Assert.notNull(getStartIndex(), "Start index must be not null!");
final T start = Assert.notNull(getBeginIndex(), "Start index must be not null!");
final T end = Assert.notNull(getEndIndex(), "End index must be not null!");
return Convert.convert((Type) start.getClass(), NumberUtil.sub(end, start).abs());
}

View File

@ -0,0 +1,71 @@
package cn.hutool.core.math;
public class NavigatePageInfo extends PageInfo{
private final int navigatePages = 8; //导航页码数
private int[] navigatePageNumbers; //所有导航页号
public NavigatePageInfo(final int total, final int pageSize) {
super(total, pageSize);
//基本参数设定之后进行导航页面的计算
calcNavigatePageNumbers();
}
/**
* 得到所有导航页号
*
* @return {int[]}
*/
public int[] getNavigatePageNumbers() {
return navigatePageNumbers;
}
public String toString() {
final StringBuilder str = new StringBuilder(super.toString());
str.append(", {navigatePageNumbers=");
final int len = navigatePageNumbers.length;
if (len > 0) str.append(navigatePageNumbers[0]);
for (int i = 1; i < len; i++) {
str.append(" ").append(navigatePageNumbers[i]);
}
str.append("}");
return str.toString();
}
/**
* 计算导航页
*/
private void calcNavigatePageNumbers() {
//当总页数小于或等于导航页码数时
if (pages <= navigatePages) {
navigatePageNumbers = new int[pages];
for (int i = 0; i < pages; i++) {
navigatePageNumbers[i] = i + 1;
}
} else { //当总页数大于导航页码数时
navigatePageNumbers = new int[navigatePages];
int startNum = pageNo - navigatePages / 2;
int endNum = pageNo + navigatePages / 2;
if (startNum < 1) {
startNum = 1;
//(最前navPageCount页
for (int i = 0; i < navigatePages; i++) {
navigatePageNumbers[i] = startNum++;
}
} else if (endNum > pages) {
endNum = pages;
//最后navPageCount页
for (int i = navigatePages - 1; i >= 0; i--) {
navigatePageNumbers[i] = endNum--;
}
} else {
//所有中间页
for (int i = 0; i < navigatePages; i++) {
navigatePageNumbers[i] = startNum++;
}
}
}
}
}

View File

@ -0,0 +1,291 @@
package cn.hutool.core.math;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.DefaultSegment;
import cn.hutool.core.lang.Segment;
/**
* 分页信息通过提供的总数页码每页记录数等信息计算总页数等信息<br>
* 来自https://bbs.csdn.net/topics/360010907
*
* @author 莫取网名
*/
public class PageInfo {
private static final int DEFAULT_PAGE_SIZE = 10;
/**
* 创建{@code PageInfo}默认当前页是1
*
* @param total 总记录数
* @param pageSize 每页显示记录数
* @return {@code PageInfo}
*/
public static PageInfo of(final int total, final int pageSize) {
return new PageInfo(total, pageSize);
}
/**
* 总记录数
*/
int total;
/**
* 每页显示记录数
*/
int pageSize;
/**
* 总页数
*/
int pages;
/**
* 首页标识
*/
int firstPageNo = 1;
/**
* 当前页
*/
int pageNo = firstPageNo;
/**
* 构造
*
* @param total 总记录数
* @param pageSize 每页显示记录数
*/
public PageInfo(final int total, final int pageSize) {
init(total, pageSize);
}
/**
* 初始化
*
* @param total 总记录数
* @param pageSize 每页显示记录数
*/
private void init(final int total, int pageSize) {
Assert.isTrue(total >= 0, "Total must >= 0");
//设置基本参数
this.total = total;
if (pageSize < 1) {
pageSize = DEFAULT_PAGE_SIZE;
}
this.pageSize = pageSize;
// 因为总条数除以页大小的最大余数是页大小数-1
// 因此加一个最大余数保证舍弃的余数与最大余数凑1.x就是一旦有余数则+1页
this.pages = (total + pageSize - 1) / pageSize;
}
/**
* 得到记录总数
*
* @return {int}
*/
public int getTotal() {
return total;
}
/**
* 得到每页显示多少条记录
*
* @return {int}
*/
public int getPageSize() {
return pageSize;
}
/**
* 得到页面总数
*
* @return {int}
*/
public int getPages() {
return pages;
}
/**
* 得到当前页号
*
* @return {int}
*/
public int getPageNo() {
return pageNo;
}
/**
* 是否首页
*
* @return 是否首页
*/
public boolean isFirstPage() {
return getPageIndexBase1() == 1;
}
/**
* 是否尾页
*
* @return 是否尾页
*/
public boolean isLastPage() {
return getPageIndexBase1() == this.pages;
}
/**
* 是否有前一页
*
* @return 是否有前一页
*/
public boolean hasPreviousPage() {
return getPageIndexBase1() > 1;
}
/**
* 是否有下一页
*
* @return 是否有下一页
*/
public boolean hasNextPage() {
return getBeginIndex() < this.pages;
}
/**
* 当前页是否可用是否大于firstPageNum且小于总页数
* @return 是否可用
*/
public boolean isValidPage(){
return this.getPageIndexBase1() <= this.pages;
}
/**
* 获取当前页的开始记录index包含
*
* @return 开始记录index包含
*/
public int getBeginIndex() {
return (getPageIndexBase1() -1) * this.pageSize;
}
/**
* 获取当前页的结束记录index不包含
* <ul>
* <li>当开始index超出total时返回正常值</li>
* <li>当开始index未超出total但是计算的end超出时返回total + 1</li>
* <li>当开始index和end都未超出时返回正常值</li>
* </ul>
*
* @return 结束记录index不包含
*/
public int getEndIndexExclude() {
return getEndIndex() + 1;
}
/**
* 获取当前页的结束记录index包含
* <ul>
* <li>当开始index超出total时返回正常值</li>
* <li>当开始index未超出total但是计算的end超出时返回total</li>
* <li>当开始index和end都未超出时返回正常值</li>
* </ul>
*
* @return 结束记录index包含
*/
public int getEndIndex() {
final int begin = getBeginIndex();
int end = begin + this.pageSize - 1;
if (begin <= this.total && end > this.total) {
end = this.total;
}
return end;
}
/**
* 将页数和每页条目数转换为开始位置和结束位置<br>
* 此方法用于包括结束位置的分页方法<br>
* 例如
* <pre>
* 页码1每页10 = [0, 9]
* 页码2每页10 = [10, 19]
*
* </pre>
*
* @return {@link Segment}
*/
public Segment<Integer> getSegment() {
return new DefaultSegment<>(getBeginIndex(), getEndIndex());
}
/**
* 获取设置首页编号即以数字几为第一页标志
*
* @return 设置首页编号
*/
public int getFirstPageNo() {
return this.firstPageNo;
}
/**
* 设置首页编号即以数字几为第一页标志<br>
* 如设置0则0表示第一页1表示第二页
*
* @param firstPageNo 首页编号
* @return this
*/
public PageInfo setFirstPageNo(final int firstPageNo) {
this.firstPageNo = firstPageNo;
return this;
}
/**
* 设置当前页码
*
* @param pageNo 当前页码
* @return this
*/
public PageInfo setPageNo(final int pageNo) {
//根据输入可能错误的当前号码进行自动纠正
// 不判断后边界因为当页码超出边界应该返回一个空区间的数据而非始终保持在最后一页
this.pageNo = Math.max(pageNo, firstPageNo);
return this;
}
/**
* 下一页即当前页码+1
*
* @return this
*/
public PageInfo nextPage() {
return setPageNo(this.pageNo + 1);
}
/**
* 上一页即当前页码-1,直到第一页则始终为第一页
*
* @return this
*/
public PageInfo PreviousPage() {
return setPageNo(this.pageNo - 1);
}
public String toString() {
return "{" +
"total=" + total +
",pages=" + pages +
",pageNumber=" + pageNo +
",limit=" + pageSize +
",isFirstPage=" + isFirstPage() +
",isLastPage=" + isLastPage() +
",hasPreviousPage=" + hasPreviousPage() +
",hasNextPage=" + hasNextPage() +
"}";
}
/**
* 获取页码序号第一个序号就是1
* @return 页码序号
*/
private int getPageIndexBase1(){
return this.pageNo - this.firstPageNo + 1;
}
}

View File

@ -171,7 +171,7 @@ public final class SensitiveUtil {
} : sensitiveProcessor;
final Map<Integer, FoundWord> foundWordMap = new HashMap<>(foundWordList.size(), 1);
foundWordList.forEach(foundWord -> foundWordMap.put(foundWord.getStartIndex(), foundWord));
foundWordList.forEach(foundWord -> foundWordMap.put(foundWord.getBeginIndex(), foundWord));
final int length = text.length();
final StringBuilder textStringBuilder = new StringBuilder();
for (int i = 0; i < length; i++) {

View File

@ -1,273 +0,0 @@
package cn.hutool.core.util;
import cn.hutool.core.lang.DefaultSegment;
import cn.hutool.core.lang.Segment;
/**
* 分页工具类
*
* @author xiaoleilu
*/
public class PageUtil {
private static int firstPageNo = 0;
/**
* 获得首页的页码可以为0或者1
*
* @return 首页页码
*/
public static int getFirstPageNo() {
return firstPageNo;
}
/**
* 设置首页页码可以为0或者1
*
* <pre>
* 当设置为0时页码0表示第一页开始位置为0
* 当设置为1时页码1表示第一页开始位置为0
* </pre>
*
* @param customFirstPageNo 自定义的首页页码为0或者1
*/
synchronized public static void setFirstPageNo(final int customFirstPageNo) {
firstPageNo = customFirstPageNo;
}
/**
* 设置首页页码为1
*
* <pre>
* 当设置为1时页码1表示第一页开始位置为0
* </pre>
*/
public static void setOneAsFirstPageNo() {
setFirstPageNo(1);
}
/**
* 将页数和每页条目数转换为开始位置<br>
* 此方法用于不包括结束位置的分页方法<br>
* 例如
*
* <pre>
* 页码0每页10 = 0
* 页码1每页10 = 10
*
* </pre>
*
* <p>
* {@link #setFirstPageNo(int)}设置为1时
* <pre>
* 页码1每页10 = 0
* 页码2每页10 = 10
*
* </pre>
*
* @param pageNo 页码从0计数
* @param pageSize 每页条目数
* @return 开始位置
*/
public static int getStart(int pageNo, int pageSize) {
if (pageNo < firstPageNo) {
pageNo = firstPageNo;
}
if (pageSize < 1) {
pageSize = 0;
}
return (pageNo - firstPageNo) * pageSize;
}
/**
* 将页数和每页条目数转换为结束位置<br>
* 此方法用于不包括结束位置的分页方法<br>
* 例如
*
* <pre>
* 页码0每页10 = 9
* 页码1每页10 = 19
*
* </pre>
*
* <p>
* {@link #setFirstPageNo(int)}设置为1时
* <pre>
* 页码1每页10 = 10
* 页码2每页10 = 20
*
* </pre>
*
* @param pageNo 页码从0计数
* @param pageSize 每页条目数
* @return 开始位置
* @since 5.2.5
*/
public static int getEnd(final int pageNo, final int pageSize) {
final int start = getStart(pageNo, pageSize);
return getEndByStart(start, pageSize);
}
/**
* 将页数和每页条目数转换为开始位置和结束位置<br>
* 此方法用于包括结束位置的分页方法<br>
* 例如
*
* <pre>
* 页码0每页10 = [0, 10]
* 页码1每页10 = [10, 20]
*
* </pre>
*
* <p>
* {@link #setFirstPageNo(int)}设置为1时
* <pre>
* 页码1每页10 = [0, 10]
* 页码2每页10 = [10, 20]
*
* </pre>
*
* @param pageNo 页码从0计数
* @param pageSize 每页条目数
* @return 第一个数为开始位置第二个数为结束位置
*/
public static int[] transToStartEnd(final int pageNo, final int pageSize) {
final int start = getStart(pageNo, pageSize);
return new int[]{start, getEndByStart(start, pageSize)};
}
/**
* 将页数和每页条目数转换为开始位置和结束位置<br>
* 此方法用于包括结束位置的分页方法<br>
* 例如
*
* <pre>
* 页码0每页10 = [0, 10]
* 页码1每页10 = [10, 20]
*
* </pre>
*
* <p>
* {@link #setFirstPageNo(int)}设置为1时
* <pre>
* 页码1每页10 = [0, 10]
* 页码2每页10 = [10, 20]
*
* </pre>
*
* @param pageNo 页码从0计数
* @param pageSize 每页条目数
* @return {@link Segment}
* @since 5.5.3
*/
public static Segment<Integer> toSegment(final int pageNo, final int pageSize) {
final int[] startEnd = transToStartEnd(pageNo, pageSize);
return new DefaultSegment<>(startEnd[0], startEnd[1]);
}
/**
* 根据总数计算总页数
*
* @param totalCount 总数
* @param pageSize 每页数
* @return 总页数
*/
public static int totalPage(final int totalCount, final int pageSize) {
return totalPage((long) totalCount, pageSize);
}
/**
* 根据总数计算总页数
*
* @param totalCount 总数
* @param pageSize 每页数
* @return 总页数
* @since 5.8.5
*/
public static int totalPage(final long totalCount, final int pageSize) {
if (pageSize == 0) {
return 0;
}
return Math.toIntExact(totalCount % pageSize == 0
? (totalCount / pageSize) : (totalCount / pageSize + 1));
}
/**
* 分页彩虹算法<br>
* 来自<a href="https://github.com/iceroot/iceroot/blob/master/src/main/java/com/icexxx/util/IceUtil.java">https://github.com/iceroot/iceroot/blob/master/src/main/java/com/icexxx/util/IceUtil.java</a><br>
* 通过传入的信息生成一个分页列表显示
*
* @param pageNo 当前页
* @param totalPage 总页数
* @param displayCount 每屏展示的页数
* @return 分页条
*/
public static int[] rainbow(final int pageNo, final int totalPage, final int displayCount) {
// displayCount % 2
final boolean isEven = (displayCount & 1) == 0;
final int left = displayCount >> 1;
int right = displayCount >> 1;
int length = displayCount;
if (isEven) {
right++;
}
if (totalPage < displayCount) {
length = totalPage;
}
final int[] result = new int[length];
if (totalPage >= displayCount) {
if (pageNo <= left) {
for (int i = 0; i < result.length; i++) {
result[i] = i + 1;
}
} else if (pageNo > totalPage - right) {
for (int i = 0; i < result.length; i++) {
result[i] = i + totalPage - displayCount + 1;
}
} else {
for (int i = 0; i < result.length; i++) {
result[i] = i + pageNo - left + (isEven ? 1 : 0);
}
}
} else {
for (int i = 0; i < result.length; i++) {
result[i] = i + 1;
}
}
return result;
}
/**
* 分页彩虹算法(默认展示10页)<br>
* 来自<a href="https://github.com/iceroot/iceroot/blob/master/src/main/java/com/icexxx/util/IceUtil.java">https://github.com/iceroot/iceroot/blob/master/src/main/java/com/icexxx/util/IceUtil.java</a>
*
* @param currentPage 当前页
* @param pageCount 总页数
* @return 分页条
*/
public static int[] rainbow(final int currentPage, final int pageCount) {
return rainbow(currentPage, pageCount, 10);
}
//------------------------------------------------------------------------- Private method start
/**
* 根据起始位置获取结束位置
*
* @param start 起始位置
* @param pageSize 每页条目数
* @return 结束位置
*/
private static int getEndByStart(final int start, int pageSize) {
if (pageSize < 1) {
pageSize = 0;
}
return start + pageSize;
}
//------------------------------------------------------------------------- Private method end
}

View File

@ -864,7 +864,7 @@ public class CollUtilTest {
objects.add(Dict.of().set("name", "姓名:" + i));
}
Assert.assertEquals(0, CollUtil.page(3, 5, objects).size());
Assert.assertEquals(0, ListUtil.page(objects, 3, 5).size());
}
@Test

View File

@ -2,7 +2,7 @@ package cn.hutool.core.collection;
import cn.hutool.core.date.StopWatch;
import cn.hutool.core.lang.Console;
import cn.hutool.core.util.PageUtil;
import cn.hutool.core.math.PageInfo;
import cn.hutool.core.util.RandomUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
@ -10,11 +10,7 @@ import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
public class ListUtilTest {
@ -105,51 +101,32 @@ public class ListUtilTest {
}
@Test
public void pageTest() {
public void pageTest1() {
final List<Integer> a = ListUtil.ofLinked(1, 2, 3, 4, 5);
PageUtil.setFirstPageNo(1);
final int[] a_1 = ListUtil.page(1, 2, a).stream().mapToInt(Integer::valueOf).toArray();
final int[] a1 = ListUtil.page(1, 2, a).stream().mapToInt(Integer::valueOf).toArray();
final int[] a2 = ListUtil.page(2, 2, a).stream().mapToInt(Integer::valueOf).toArray();
final int[] a3 = ListUtil.page(3, 2, a).stream().mapToInt(Integer::valueOf).toArray();
final int[] a4 = ListUtil.page(4, 2, a).stream().mapToInt(Integer::valueOf).toArray();
final int[] a_1 = ListUtil.page(a, 0, 2).stream().mapToInt(Integer::valueOf).toArray();
final int[] a1 = ListUtil.page(a, 0, 2).stream().mapToInt(Integer::valueOf).toArray();
final int[] a2 = ListUtil.page(a, 1, 2).stream().mapToInt(Integer::valueOf).toArray();
final int[] a3 = ListUtil.page(a, 2, 2).stream().mapToInt(Integer::valueOf).toArray();
final int[] a4 = ListUtil.page(a, 3, 2).stream().mapToInt(Integer::valueOf).toArray();
Assert.assertArrayEquals(new int[]{1, 2}, a_1);
Assert.assertArrayEquals(new int[]{1, 2}, a1);
Assert.assertArrayEquals(new int[]{3, 4}, a2);
Assert.assertArrayEquals(new int[]{5}, a3);
Assert.assertArrayEquals(new int[]{}, a4);
}
PageUtil.setFirstPageNo(2);
final int[] b_1 = ListUtil.page(1, 2, a).stream().mapToInt(Integer::valueOf).toArray();
final int[] b1 = ListUtil.page(2, 2, a).stream().mapToInt(Integer::valueOf).toArray();
final int[] b2 = ListUtil.page(3, 2, a).stream().mapToInt(Integer::valueOf).toArray();
final int[] b3 = ListUtil.page(4, 2, a).stream().mapToInt(Integer::valueOf).toArray();
final int[] b4 = ListUtil.page(5, 2, a).stream().mapToInt(Integer::valueOf).toArray();
Assert.assertArrayEquals(new int[]{1, 2}, b_1);
Assert.assertArrayEquals(new int[]{1, 2}, b1);
Assert.assertArrayEquals(new int[]{3, 4}, b2);
Assert.assertArrayEquals(new int[]{5}, b3);
Assert.assertArrayEquals(new int[]{}, b4);
PageUtil.setFirstPageNo(0);
final int[] c_1 = ListUtil.page(-1, 2, a).stream().mapToInt(Integer::valueOf).toArray();
final int[] c1 = ListUtil.page(0, 2, a).stream().mapToInt(Integer::valueOf).toArray();
final int[] c2 = ListUtil.page(1, 2, a).stream().mapToInt(Integer::valueOf).toArray();
final int[] c3 = ListUtil.page(2, 2, a).stream().mapToInt(Integer::valueOf).toArray();
final int[] c4 = ListUtil.page(3, 2, a).stream().mapToInt(Integer::valueOf).toArray();
Assert.assertArrayEquals(new int[]{1, 2}, c_1);
Assert.assertArrayEquals(new int[]{1, 2}, c1);
Assert.assertArrayEquals(new int[]{3, 4}, c2);
Assert.assertArrayEquals(new int[]{5}, c3);
Assert.assertArrayEquals(new int[]{}, c4);
PageUtil.setFirstPageNo(1);
final int[] d1 = ListUtil.page(0, 8, a).stream().mapToInt(Integer::valueOf).toArray();
@Test
public void pageTest2() {
final List<Integer> a = ListUtil.ofLinked(1, 2, 3, 4, 5);
final int[] d1 = ListUtil.page(a, PageInfo.of(a.size(), 8).setFirstPageNo(0).setPageNo(0))
.stream().mapToInt(Integer::valueOf).toArray();
Assert.assertArrayEquals(new int[]{1, 2, 3, 4, 5}, d1);
}
@Test
public void pageTest3() {
final List<Integer> a = ListUtil.ofLinked(1, 2, 3, 4, 5);
// page with consumer
final List<List<Integer>> pageListData = new ArrayList<>();
ListUtil.page(a, 2, pageListData::add);
@ -168,9 +145,6 @@ public class ListUtilTest {
Assert.assertArrayEquals(new int[]{}, pageListData.get(0).stream().mapToInt(Integer::valueOf).toArray());
Assert.assertArrayEquals(new int[]{3, 4}, pageListData.get(1).stream().mapToInt(Integer::valueOf).toArray());
Assert.assertArrayEquals(new int[]{5}, pageListData.get(2).stream().mapToInt(Integer::valueOf).toArray());
// 恢复默认值避免影响其他测试用例
PageUtil.setFirstPageNo(0);
}
@Test

View File

@ -0,0 +1,32 @@
package cn.hutool.core.math;
import org.junit.Assert;
import org.junit.Test;
public class PageInfoTest {
@Test
public void pagesTest() {
PageInfo pageInfo = new PageInfo(20, 3);
Assert.assertEquals(7, pageInfo.getPages());
pageInfo = new PageInfo(20, 4);
Assert.assertEquals(5, pageInfo.getPages());
}
@Test
public void getSegmentTest() {
final PageInfo page = PageInfo.of(20, 10);
Assert.assertEquals("[0, 9]", page.getSegment().toString());
Assert.assertEquals("[10, 19]", page.nextPage().getSegment().toString());
Assert.assertEquals("[20, 20]", page.nextPage().getSegment().toString());
}
@Test
public void getSegmentTest2() {
final PageInfo page = PageInfo.of(20, 10);
page.setFirstPageNo(0).setPageNo(0);
Assert.assertEquals("[0, 9]", page.getSegment().toString());
Assert.assertEquals("[10, 19]", page.nextPage().getSegment().toString());
Assert.assertEquals("[20, 20]", page.nextPage().getSegment().toString());
}
}

View File

@ -91,15 +91,15 @@ public class DfaTest {
Assert.assertEquals(3, result.size());
Assert.assertEquals("", result.get(0).getWord());
Assert.assertEquals(0, result.get(0).getStartIndex().intValue());
Assert.assertEquals(0, result.get(0).getBeginIndex().intValue());
Assert.assertEquals(0, result.get(0).getEndIndex().intValue());
Assert.assertEquals("赵阿", result.get(1).getWord());
Assert.assertEquals(0, result.get(1).getStartIndex().intValue());
Assert.assertEquals(0, result.get(1).getBeginIndex().intValue());
Assert.assertEquals(1, result.get(1).getEndIndex().intValue());
Assert.assertEquals("赵阿三", result.get(2).getWord());
Assert.assertEquals(0, result.get(2).getStartIndex().intValue());
Assert.assertEquals(0, result.get(2).getBeginIndex().intValue());
Assert.assertEquals(2, result.get(2).getEndIndex().intValue());
}

View File

@ -1,35 +0,0 @@
package cn.hutool.core.util;
import org.junit.Assert;
import org.junit.Test;
/**
* 分页单元测试
*
* @author Looly
*/
public class PageUtilTest {
@Test
public void transToStartEndTest() {
final int[] startEnd1 = PageUtil.transToStartEnd(0, 10);
Assert.assertEquals(0, startEnd1[0]);
Assert.assertEquals(10, startEnd1[1]);
final int[] startEnd2 = PageUtil.transToStartEnd(1, 10);
Assert.assertEquals(10, startEnd2[0]);
Assert.assertEquals(20, startEnd2[1]);
}
@Test
public void totalPage() {
final int totalPage = PageUtil.totalPage(20, 3);
Assert.assertEquals(7, totalPage);
}
@Test
public void rainbowTest() {
final int[] rainbow = PageUtil.rainbow(5, 20, 6);
Assert.assertArrayEquals(new int[]{3, 4, 5, 6, 7, 8}, rainbow);
}
}

View File

@ -1,8 +1,8 @@
package cn.hutool.db;
import cn.hutool.core.lang.Segment;
import cn.hutool.core.math.PageInfo;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.PageUtil;
import cn.hutool.db.sql.Order;
import java.io.Serializable;
@ -16,6 +16,9 @@ import java.util.Arrays;
public class Page implements Segment<Integer>, Serializable {
private static final long serialVersionUID = 97792549823353462L;
/**
* 默认
*/
public static final int DEFAULT_PAGE_SIZE = 20;
/**
@ -140,15 +143,16 @@ public class Page implements Segment<Integer>, Serializable {
/**
* @return 开始位置
* @see #getStartIndex()
* @see #getBeginIndex()
*/
public int getStartPosition() {
return getStartIndex();
return getBeginIndex();
}
@Override
public Integer getStartIndex() {
return PageUtil.getStart(this.pageNumber, this.pageSize);
public Integer getBeginIndex() {
return PageInfo.of(Integer.MAX_VALUE, this.pageSize)
.setFirstPageNo(0).setPageNo(this.pageNumber).getBeginIndex();
}
/**
@ -161,7 +165,7 @@ public class Page implements Segment<Integer>, Serializable {
@Override
public Integer getEndIndex() {
return PageUtil.getEnd(this.pageNumber, this.pageSize);
return PageInfo.of(Integer.MAX_VALUE, this.pageSize).setFirstPageNo(0).getEndIndex();
}
/**
@ -178,7 +182,9 @@ public class Page implements Segment<Integer>, Serializable {
* @return 第一个数为开始位置第二个数为结束位置
*/
public int[] getStartEnd() {
return PageUtil.transToStartEnd(pageNumber, pageSize);
final PageInfo pageInfo = PageInfo.of(Integer.MAX_VALUE, this.pageSize)
.setFirstPageNo(0).setPageNo(this.pageNumber);
return new int[]{pageInfo.getBeginIndex(), pageInfo.getEndIndexExclude()};
}
@Override

View File

@ -1,6 +1,6 @@
package cn.hutool.db;
import cn.hutool.core.util.PageUtil;
import cn.hutool.core.math.PageInfo;
import java.util.ArrayList;
@ -16,7 +16,7 @@ public class PageResult<T> extends ArrayList<T> {
public static final int DEFAULT_PAGE_SIZE = Page.DEFAULT_PAGE_SIZE;
/**
* 页码{@link PageUtil#getFirstPageNo()}表示第一页
* 页码
*/
private int page;
/**
@ -65,7 +65,7 @@ public class PageResult<T> extends ArrayList<T> {
this(page, pageSize);
this.total = total;
this.totalPage = PageUtil.totalPage(total, pageSize);
this.totalPage = PageInfo.of(total, pageSize).getPages();
}
//---------------------------------------------------------- Constructor end
@ -142,7 +142,7 @@ public class PageResult<T> extends ArrayList<T> {
* @return 是否第一页
*/
public boolean isFirst() {
return this.page == PageUtil.getFirstPageNo();
return this.page == 0;
}
/**

View File

@ -34,7 +34,8 @@ public class DbTest {
@Test
public void pageTest() {
// 测试数据库中一共4条数据第0页有3条第1页有1条
final List<Entity> page0 = Db.of().page(Entity.of("user"), Page.of(0, 3));
final List<Entity> page0 = Db.of().page(Entity.of("user"),
Page.of(0, 3));
Assert.assertEquals(3, page0.size());
final List<Entity> page1 = Db.of().page(Entity.of("user"), Page.of(1, 3));