通过Stream对List进行分页、动态排序
开发时有些场景需要对数据进行分页或根据某个字段排序,通常在数据库中即可完成,但是往往业务需求会在数据库中查询出来以后做一些更多的业务操作,无法直接通过数据库分页、排序,可以通过Stream流对集合进行分页、动态排序。
用到的Maven依赖
<!-- lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.3.21</version>
</dependency>
ListUtil代码
package com.example;
import lombok.SneakyThrows;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.util.comparator.Comparators;
import java.lang.reflect.Method;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class ListUtil {
/**
* 给List进行排序、分页
* @param dataList 数据集合
* @param clazz 集合数据类型
* @param asc 是否正序
* @param pageNum 当前页
* @param pageSize 每页数量
* @param orderByColumn 排序字段
* @return 集合
* @param <T> 集合数据类型
*/
public static <T> List<T> page(List<T> dataList, Class<T> clazz, boolean asc, Long pageNum, Long pageSize, String orderByColumn) {
//空集合直接返回原List
if (CollectionUtils.isEmpty(dataList)) {
return dataList;
}
//根据排序字段、是否正序排序
if (StringUtils.hasText(orderByColumn)) {
dataList.sort(comparable(clazz, orderByColumn, asc));
}
//分页参数确实直接返回原List
if (Objects.isNull(pageNum) || Objects.isNull(pageSize)) {
return dataList;
}
//对排序完的集合进行分页
return dataList.stream().skip(pageSize * (pageNum - 1)).limit(pageSize).collect(Collectors.toList());
}
/**
* 对List进行排序
* @param dataList 数据集合
* @param clazz 集合数据类型
* @param asc 是否正序
* @param orderByColumn 排序字段
* @return 集合
* @param <T> 集合数据类型
*/
public static <T> List<T> page(List<T> dataList, Class<T> clazz, boolean asc, String orderByColumn) {
return page(dataList, clazz, asc, null, null, orderByColumn);
}
/**
* 排序
* @param clazz 类型
* @param orderByColumn 排序字段
* @param isAsc 是否正序
* @return 排序
* @param <T> 类型
*/
private static <T> Comparator<? super T> comparable(Class<T> clazz, String orderByColumn, boolean isAsc) {
Method getterMethod = BeanUtils.findGetterMethod(clazz, orderByColumn);
Comparator<T> tComparator = (c1, c2) -> {
try {
Object c1v = getterMethod.invoke(c1);
Object c2v = getterMethod.invoke(c2);
return Comparators.comparable().compare(Optional.ofNullable(c1v).orElse(""), Optional.ofNullable(c2v).orElse(""));
} catch (Exception e) {
e.printStackTrace();
//TODO 这里可以做一些报错的提醒
}
return 0;
};
return isAsc ? tComparator : tComparator.reversed();
}
//过滤
public static <T> List<T> filter(List<T> dataList, Predicate<T> predicate) {
return dataList.stream().filter(predicate).collect(Collectors.toList());
}
/**
* 通过反射获取getter
*
*/
@SneakyThrows
public static <T> Method findGetterMethod(Class<T> clazz, String fieldName) {
String getterName = "get" + capitalizeFirstLetter(fieldName);
return clazz.getMethod(getterName);
}
/**
* 首字母大写
* @param s
* @return
*/
public static String capitalizeFirstLetter(String s) {
return Character.toUpperCase(s.charAt(0)) + s.substring(1);
}
}
测试
public static class User {
private Long id;
private String userName;
public User(Long id, String userName) {
this.id = id;
this.userName = userName;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", userName='" + userName + '\'' +
'}';
}
}
测试代码
@Test
public void test() {
ArrayList<User> users = new ArrayList<User>();
users.add(new User(1L, "zhangsan"));
users.add(new User(2L, "lisi"));
users.add(new User(3L, "wangwu"));
users.add(new User(4L, "zhaoliu"));
List<User> pageList = ListUtil.page(users, User.class, false, 1L, 2L, "id");
System.out.println("pageList = " + pageList);
}
结果
pageList = [User{id=4, userName='zhaoliu'}, User{id=3, userName='wangwu'}]