java实现数据排序,通用方法

最近遇到了一个问题,那就是数据直接通过sql计算会很慢,或者是计算不出来,那么计算数据的任务只能交给java后台。
计算完数据之后,需要对数据进行排序,分页。
如果知道固定的排序规则好办,但是如果不知道规则,或者规则过多,就需要考虑通用性
而下面就是我的排序方案:
总体思路是:

  1. 判断是否为空
  2. 通过第0个元素的数据获取field的列表,考虑到了可能存在通过数据的某一属性的某一属性进行排序的可能
  3. 生成Map<排序字段, List<数据>>的数据,使用list考虑到了可能存在并列数据的可能,另外被排序的数据需要实现Comparable接口,并且泛型值要写上
  4. lambda对数据进行排序
  5. 对最终数据进行处理
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ObjectUtils;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

public class A {

    private static final Logger logger = LoggerFactory.getLogger(A.class);

    /**
     * 排序
     *
     * @param dataList
     * @param fieldNameList
     * @param isAsc
     * @param <T>
     * @param <C>
     * @return
     */
    public static <T, C extends Comparable<C>> List<T> sort (List<T> dataList, List<String> fieldNameList, boolean isAsc) {
        List<Field> fieldList = new ArrayList<>();
        if (ObjectUtils.isEmpty(dataList)) {
            return dataList;
        }

        Class<?> dataClass = dataList.get(0).getClass();
        for (String name : fieldNameList) { // 循环获取field列表
            Field field = getField(dataClass, name);
            fieldList.add(field);
            dataClass = field.getType();
        }

        Map<C, List<T>> dataMap = new HashMap(); // 有多条数据同一值的可能
        dataList.forEach(data -> { // 获取数据Map,
            C key = (C) getData(data, fieldList);
            if (dataMap.containsKey(key)) {
                dataMap.get(key).add(data);
            } else {
                dataMap.put(key, new ArrayList<T>() {{
                    add(data);
                }});
            }
        });

        List<List<T>> tempList;
        if (isAsc) { // 升序
            tempList = dataMap.entrySet().stream().sorted(Map.Entry.comparingByKey(Comparator.nullsFirst(Comparator.naturalOrder())))
                    .map(Map.Entry::getValue).collect(Collectors.toList());
        } else { // 降序
            tempList = dataMap.entrySet().stream().sorted(Map.Entry.comparingByKey(Comparator.nullsFirst(Comparator.reverseOrder())))
                    .map(Map.Entry::getValue).collect(Collectors.toList());
        }
        List<T> resultList = new ArrayList<T>();
        tempList.forEach(data -> {
            data.forEach(d -> {
                resultList.add(d);
            });
        });
        return resultList;
    }

    /**
     * 根据field列表,获取数据
     * @param source
     * @param fieldList
     * @return
     */
    public static Object getData (Object source, List<Field> fieldList) {
        try {
            Object obj = fieldList.get(0).get(source);
            if (fieldList.size() == 1) {
                return obj;
            }
            return getDataRecursion(obj, fieldList.subList(1, fieldList.size())); // 多条数据,递归查询
        } catch (IllegalAccessException e) {
            logger.error("", e);
        }
        return source;
    }

    /**
     * 递归获取属性列表
     * @param source
     * @param fieldList
     * @return
     */
    public static Object getDataRecursion (Object source, List<Field> fieldList) {
        for (Field field : fieldList) {
            try {
                source = field.get(source);
            } catch (IllegalAccessException e) {
                logger.error("", e);
            }
        }
        return source;
    }

    /**
     * 根据name,获取class的Field
     * @param dataClass
     * @param fieldName
     * @return
     */
    public static Field getField (Class dataClass, String fieldName) {
        Field field = getEntityFieldByFieldName(dataClass, fieldName);
        return field;
    }

    /**
     * 根据属性名,获取对象field,field可获取数据
     */
    public static <T> Field getEntityFieldByFieldName (Class clazz, String fieldName) {
        try {
            // 寻找泛型Field
            Field targetField = null;

            for (; clazz != null; clazz = clazz.getSuperclass()) {
                Field[] fields = clazz.getDeclaredFields();
                try {
                    targetField = clazz.getDeclaredField(fieldName);
                    break;
                } catch (Exception e) {
                    continue;
                }
            }
            targetField.setAccessible(true);
            return targetField;
        } catch (Exception e) { // 这个异常基本不可能发生,若发生就是因为程序出现了bug,那就让你空指针吧
            logger.error("", e);
            return null;
        }
    }
}
原文地址:https://www.cnblogs.com/season-qd/p/13748710.html