通用实例列表排序实现
1. ModelsSortHelper
import com.google.common.base.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import lombok.Data;
/**
* Model列表排序帮助类
*/
public class ModelsSortHelper {
/**
* Model列表排序
*
* @param sortStr 排序条件.(必须以 字段名1__asc|desc[,字段名2__asc|desc...] 这样的格式.如 "name_asc,age_desc")
* 对应的字段必须实现 Comparable 接口
* @param source 列表
* @param tClass Model类型
* @param <T> Model类型
* @return 排序后的列表
*/
public static <T> List<T> sort(String sortStr, List<T> source, Class<T> tClass) {
// 转换排序条件列表
List<SortItem> keys = toKeys(sortStr);
// 如果没有排序条件,直接返回原列表
if (CollectionUtils.isEmpty(keys)) {
return source;
}
if (CollectionUtils.isEmpty(keys)) {
return source;
}
//根据排序条件列表构建 比较器Comparator<T>
Comparator<T> comparator = buildComparator(keys, tClass);
// 如果构建失败(字段不存在,字段类型没有实现Comparable等),直接返回原列表
if (comparator == null) {
return source;
}
// 实现排序
return source.stream()
.sorted(comparator)
.collect(Collectors.toList());
}
/**
* 转换为排序算法列表
*
* @param sortType 排序算法
*/
private static List<SortItem> toKeys(String sortType) {
if (Strings.isNullOrEmpty(sortType)) {
return Collections.emptyList();
}
String[] sortItems = sortType.split(",");
return Arrays.stream(sortItems)
.map(SortItem::new)
.collect(Collectors.toList());
}
/**
* 构建比较器链
*
* @param sorts 排序列表
* @param tClass Model类型
* @param <T> Model类型
* @return 比较器
*/
private static <T> Comparator<T> buildComparator(List<SortItem> sorts, Class<T> tClass) {
// 多个Sort条件,则实现 Comparator的thenComparing
Comparator<T> comparator = null;
for (SortItem sort : sorts) {
Comparator<T> theComparator = buildComparator(sort, tClass);
if (theComparator == null) {
throw new RuntimeException("创建比较器异常.对应的排序字段为:" + sort.getField());
}
// 第一个排序条件为主排序
if (comparator == null) {
comparator = theComparator;
} else {
// 第2个及以后的为辅助排序
comparator = comparator.thenComparing(theComparator);
}
}
return comparator;
}
/**
* 构建单个比较器
*
* @param sortItem 排序列表
* @param tClass Model类型
* @param <T> Model类型
* @return 比较器
*/
private static <T> Comparator<T> buildComparator(SortItem sortItem, Class<T> tClass) {
String field = sortItem.getField();
return (T o1, T o2) -> sortItem.isAsc()
? getVal(o1, tClass, field).compareTo(getVal(o2, tClass, field))
: getVal(o2, tClass, field).compareTo(getVal(o1, tClass, field));
}
/**
* 获取字段对应的值的方法
* @param instance 比较实例
* @param tClass Model类型
* @param field 比较字段
* @param <T> Model类型
* @return 返回一个Comparable 类型的值
*/
private static <T> Comparable getVal(T instance, Class<T> tClass, String field) {
// BeanUtils 已缓存到一个Map里
PropertyDescriptor propertyDescriptor = BeanUtils.getPropertyDescriptor(tClass, field);
Method readMethod = propertyDescriptor.getReadMethod();
try {
Object val = readMethod.invoke(instance);
if (val instanceof Comparable) {
return (Comparable) val;
}
} catch (Exception ex) {
throw new RuntimeException("配置排序字段异常-1");
}
throw new RuntimeException("配置排序字段异常-3");
}
@Data
static class SortItem {
private String field;
private String type;
public SortItem(String sort) {
String[] arr = sort.split("__");
Assert.isTrue(arr.length == 2);
Assert.isTrue(!Strings.isNullOrEmpty(arr[0]) && !Strings.isNullOrEmpty(arr[1]));
Assert.isTrue("asc".equalsIgnoreCase(arr[1]) || "desc".equalsIgnoreCase(arr[1]));
field = arr[0];
type = arr[1];
}
public boolean isAsc() {
return "asc".equalsIgnoreCase(type);
}
}
}

![通用实例列表排序实现
[编程语言教程]](https://www.zixueka.com/wp-content/uploads/2024/01/1706713473-a30a71333886f53.jpg)
