• 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;
            }
        }
    }
    
  • 相关阅读:
    各种读取速度
    索引倒排
    清空mysql数据
    java随机读取文件
    移动文件
    输出字符串数组
    背包问题
    使用bloomfilter
    使用hash拆分文件
    判断文件的编码格式
  • 原文地址:https://www.cnblogs.com/season-qd/p/13748710.html
Copyright © 2020-2023  润新知