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;
        }
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM