根据对象属性名进行List集合排序
功能描述:
非数据实体VO需要进行排序分页
前置条件:
1.使用java8;
2.使用Spring框架;
3.排序字段实现Comparable接口。
参数描述:
sort :排序字段;
mode:升序或降序;
page:当前页;
limit:限制条数。
代码展示:
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Field;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* List集合排序分页
*
* @author tuojinhui
* @date 2019-09-11
*/
public class SortPageUtils {
/**
* List 集合排序
* --data sort mode有一个为空就返回原数据
* --sort属性不存在返回原数据
* --mode非asc或desc返回原数据
* --排序属性字段返回类型不与case匹配返回原数据
*
* @param data 排序前的集合数据
* @param sort 排序属性字段 propName
* @param mode 升序降序字符 asc|desc
* @return 排序后的集合数据
*/
public static <T> List<T> sort(List<T> data, String sort, String mode) {
if (StringUtils.isNotBlank(sort) && StringUtils.isNotBlank(mode) && !CollectionUtils.isEmpty(data)) {
Class<?> fieldType = getFieldType(data.get(0).getClass(), sort);
if (fieldType == null) {
return data;
}
if ("asc".equalsIgnoreCase(mode)) {
switch (fieldType.getName()) {
case "java.lang.Byte":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Byte) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
case "java.lang.Short":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Short) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
case "java.lang.Integer":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Integer) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
case "java.lang.Long":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Long) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
case "java.lang.Float":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Float) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
case "java.lang.Double":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Double) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
case "java.lang.Boolean":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Boolean) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
case "java.lang.Character":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Character) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
case "byte":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Byte) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
case "short":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Short) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
case "int":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Integer) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
case "long":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Long) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
case "float":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Float) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
case "double":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Double) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
case "boolean":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Boolean) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
case "char":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Character) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
case "java.lang.String":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.String) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
case "java.util.Date":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.util.Date) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
case "java.math.BigDecimal":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.math.BigDecimal) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
case "java.time.LocalDate":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.time.LocalDate) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
case "java.time.LocalTime":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.time.LocalTime) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
case "java.time.LocalDateTime":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.time.LocalDateTime) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
default:
return data;
}
} else if ("desc".equalsIgnoreCase(mode)) {
switch (fieldType.getName()) {
case "java.lang.Byte":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Byte) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.reverseOrder()))).collect(Collectors.toList());
case "java.lang.Short":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Short) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.reverseOrder()))).collect(Collectors.toList());
case "java.lang.Integer":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Integer) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.reverseOrder()))).collect(Collectors.toList());
case "java.lang.Long":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Long) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.reverseOrder()))).collect(Collectors.toList());
case "java.lang.Float":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Float) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.reverseOrder()))).collect(Collectors.toList());
case "java.lang.Double":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Double) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.reverseOrder()))).collect(Collectors.toList());
case "java.lang.Boolean":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Boolean) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.reverseOrder()))).collect(Collectors.toList());
case "java.lang.Character":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Character) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.reverseOrder()))).collect(Collectors.toList());
case "byte":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Byte) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.reverseOrder()))).collect(Collectors.toList());
case "short":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Short) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.reverseOrder()))).collect(Collectors.toList());
case "int":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Integer) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.reverseOrder()))).collect(Collectors.toList());
case "long":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Long) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.reverseOrder()))).collect(Collectors.toList());
case "float":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Float) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.reverseOrder()))).collect(Collectors.toList());
case "double":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Double) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.reverseOrder()))).collect(Collectors.toList());
case "boolean":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Boolean) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.reverseOrder()))).collect(Collectors.toList());
case "char":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.Character) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.reverseOrder()))).collect(Collectors.toList());
case "java.lang.String":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.lang.String) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.reverseOrder()))).collect(Collectors.toList());
case "java.util.Date":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.util.Date) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.reverseOrder()))).collect(Collectors.toList());
case "java.math.BigDecimal":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.math.BigDecimal) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.reverseOrder()))).collect(Collectors.toList());
case "java.time.LocalDate":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.time.LocalDate) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.reverseOrder()))).collect(Collectors.toList());
case "java.time.LocalTime":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.time.LocalTime) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.reverseOrder()))).collect(Collectors.toList());
case "java.time.LocalDateTime":
return data.stream().sorted(Comparator.comparing((T obj) -> ((java.time.LocalDateTime) getFieldValue(obj, sort, fieldType)), Comparator.nullsLast(Comparator.reverseOrder()))).collect(Collectors.toList());
default:
return data;
}
}
}
return data;
}
/**
* List 集合分页
* data page limit有一个为空就返回原数据
*
* @param data 分页前的集合数据
* @param page 当前页码
* @param limit 限制条数
* @return 分页后的集合数据
*/
public static <T> List<T> page(List<T> data, Integer page, Integer limit) {
if (!ObjectUtils.isEmpty(page) && !ObjectUtils.isEmpty(limit) && !ObjectUtils.isEmpty(data)) {
return data.stream()
.skip((page - 1) * limit)
.limit(limit)
.collect(Collectors.toList());
}
return data;
}
/**
* List 集合排序分页
*/
public static <T> List<T> sortPage(List<T> data, Integer page, Integer limit, String sort, String mode) {
return page(sort(data, sort, mode), page, limit);
}
/**
* 根据属性名 获取字段类型
*
* @param clazz Class
* @param sort 属性名
* @return 属性类型
*/
private static <T> Class<?> getFieldType(Class<T> clazz, String sort) {
if (Stream.of(clazz.getDeclaredFields())
.filter(field -> field.getName().equals(sort))
.count() != 1) {
return null;
}
Field targetField = org.springframework.util.ReflectionUtils.findField(clazz, sort);
org.springframework.util.ReflectionUtils.makeAccessible(targetField);
return targetField.getType();
}
/**
* 根据属性名、字段类型 获取字段值
*
* @param obj 对象
* @param sort 属性名
* @param type 属性类型
* @return 对象为Object的字段值
*/
private static <T> Object getFieldValue(T obj, String sort, Class<?> type) {
if (Stream.of(obj.getClass().getDeclaredFields())
.filter(field -> field.getName().equals(sort))
.filter(field -> field.getType() == type)
.count() != 1) {
return null;
}
Field targetField = org.springframework.util.ReflectionUtils.findField(obj.getClass(), sort, type);
org.springframework.util.ReflectionUtils.makeAccessible(targetField);
return ReflectionUtils.getField(targetField, obj);
}
}