動態生成多字段排序,動態生成stream filter

 Comparator<Map<String, Object>> cmp = null;
            for (int i = 0; i < st.size(); i++) {
                String t = st.get(i);
                String r = sr.get(i);
                Comparator<Map<String, Object>> thiscmp = (m1, m2) -> {
                    if (r.equalsIgnoreCase("1")) {//正序
                        if (m1.get(t) == null && m2.get(t) == null) {
                            return 0;
                        } else if (m1.get(t) == null) {
                            return -1;
                        } else if (m2.get(t) == null) {
                            return 1;
                        } else {
                            return m1.get(t).toString().compareTo(m2.get(t).toString());
                        }
                    } else if (r.equalsIgnoreCase("-1")) {////逆序
                        if (m1.get(t) == null && m2.get(t) == null) {
                            return 0;
                        } else if (m1.get(t) == null) {
                            return 1;
                        } else if (m2.get(t) == null) {
                            return -1;
                        } else {
                            return -m1.get(t).toString().compareTo(m2.get(t).toString());
                        }
                    }
                    return 0;
                };
                if (cmp == null) {
                    cmp = thiscmp;
                } else {
                    cmp = cmp.thenComparing(thiscmp);
                }
            }
            if (cmp != null) {
                datas.sort(cmp);
            }
 @Test
    public void main1() throws ParseException {
        String s = "2018-04-15 00:00:00";
        boolean matches = s.trim().matches("^\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2}$");
        boolean matches2 = s.trim().matches("^\\d{4}-\\d{2}-\\d{2}$");
        boolean matches3 = s.trim().matches("^\\d{2}:\\d{2}:\\d{2}$");
        SimpleDateFormat sdfFull = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdfYMD = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdfhms = new SimpleDateFormat("HH:mm:ss");
        Date date = sdfFull.parse(s);
        System.out.println(sdfFull.format(date));
        System.out.println(sdfYMD.format(date));
        System.out.println(sdfhms.format(date));
        System.out.println(sdfhms.format(date));


    }

    @Test
    public void main2() {
//        String s = "(SECUCODE=\"102100896.IB\")(EVENT_TYPE_CODEII in (\"002001\",\"002007\",\"003004\"))(EVENT_DATE>='2014-10-31')(EVENT_DATE<='2022-03-28 08:27:12')";
        String s = "(SECUCODE=\"102100896.IB\")(EVENT_TYPE_CODEII in (\"002001\",\"002007\",\"003004\"))(EVENT_DATE>='2014-10-31')(EVENT_DATE<'2022-03-28 08:27:21')(EVENT_DATE in ('2022-03-28 08:13:05'))";//
//        String s = "(SECUCODE=\"102100896.IB\")(EVENT_TYPE_CODEII in (\"002001\",\"002007\",\"003004\"))(EVENT_DATE>='2014-10-31')(EVENT_DATE<='2022-03-28 08:27:12')";
        List<FilterModel> filterModels = FilterUtils.paramToFilterModels(s);
        List<Map<String, Object>> resultList;//Object/String/Map<String, Object>;resultList.add(null);

        try {
            byte[] bytes = Files.readAllBytes(Paths.get("src/test/java/com/eastmoney/jsonString.json"));
            String json = new String(bytes, StandardCharsets.UTF_8);
            List<Map<String, Object>> result = (List<Map<String, Object>>) com.alibaba.fastjson.JSON.parse(json);

            resultList = ListMapFilterUtil.doFilterChain(result, filterModels);
            Assert.assertTrue(resultList.size() > 0);
            Assert.assertEquals(1, resultList.size());
            System.out.println(resultList);
        } catch (Exception e) {
            Assert.fail();
            System.out.printf(e.getMessage());
        }
    }
package com.eastmoney.edas.core.paramhandler.utils;

import com.eastmoney.common.core.dto.FilterModel;
import com.eastmoney.edas.core.paramhandler.ParamHandlerException;
import com.eastmoney.edas.core.utils.AssertUtils;
import com.eastmoney.edas.core.utils.LogUtils;
import com.eastmoney.edas.core.utils.ObjectUtil;
import lombok.val;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * List&lt;Map&lt;String, Object&gt;&gt; 按照自定義 filter 做過濾
 *
 * @author gyb
 */
public class ListMapFilterUtil {

    public static final String IN = "in";
    public static final String AND = "and";
    public static final String OR = "or";
    public final static SimpleDateFormat sdfFull = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    public final static SimpleDateFormat sdfYMD = new SimpleDateFormat("yyyy-MM-dd");
    public final static SimpleDateFormat sdfHms = new SimpleDateFormat("HH:mm:ss");
    public final static Pattern patternFull = Pattern.compile("^\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2}$");
    public final static Pattern patternYMD = Pattern.compile("^\\d{4}-\\d{2}-\\d{2}$");
    public final static Pattern patternHms = Pattern.compile("^\\d{2}:\\d{2}:\\d{2}$");

    public static final List<String> IGNORE_SRC_VALUE_LIST = Arrays.asList("-", "'-'", "\"-\"");

    public static List<Map<String, Object>> doFilterChain(List<Map<String, Object>> sourceList, List<FilterModel> filterList) {

        try {
            if (filterList == null || filterList.size() == 0 || sourceList == null || sourceList.size() == 0) {
                return sourceList;
            }

            List<Map<String, Object>> resultList = new ArrayList<>(sourceList.size());

            Predicate<Map<String, Object>> rP = null;
            for (FilterModel filter : filterList) {
                if (IGNORE_SRC_VALUE_LIST.contains(filter.getValue())) {
                    continue;
                }
                Predicate<Map<String, Object>> thisP;
                if (filter.getOper().equalsIgnoreCase(IN)) {
                    thisP = getInPredicate(filter);
                } else {
                    thisP = getCmpPredicate(filter);
                }

                if (ObjectUtil.notEmpty(thisP)) {
                    if (ObjectUtil.isEmpty(rP)) {
                        rP = thisP;
                    } else if (AND.equals(filter.getLogOper())) {
                        rP = rP.and(thisP);

                    } else if (OR.equals(filter.getLogOper())) {
                        rP = rP.or(thisP);
                    }/* else if (ObjectUtil.isEmpty(thisP)) {
                     *//*continue;*//*
                    }*/
                }
            }


            if (ObjectUtil.notEmpty(rP)) {
                resultList = sourceList.stream().filter(rP).collect(Collectors.toList());
            }

            return resultList;
        } catch (Exception e) {
            LogUtils.error("", e.getMessage(), e);
        }
        return new ArrayList<>(1);
    }

    public static Predicate<Map<String, Object>> getInPredicate(FilterModel filter) throws Exception {
        AssertUtils.isTrue(filter.getOper().equalsIgnoreCase(IN), "filter 輸入有誤 IN");

        String filterValue = filter.getValue();
        if (StringUtils.isEmpty(filterValue)) {
            return x -> false;
        }
        String[] objs = filterValue.split(",");
        Object[] realObjs = new Object[objs.length];

        Type inValuesType = null;
        for (int i = 0; i < objs.length; i++) {
            realObjs[i] = getRealObjectValueFromSourceStr(objs[i]);
            if (i == 0) {
                if (realObjs[i] instanceof String) {
                    inValuesType = String.class;
                } else if (realObjs[i] instanceof Date) {
                    inValuesType = Date.class;
                } else if (realObjs[i] instanceof Double) {
                    inValuesType = Double.class;
                } else {
                    throw new Exception("filter in 中數據的格式不正確:" + filter.getKey() + " " + filter.getOper() + " " + filter.getValue() + "$" + filter.getLogOper());//根本不是 日期類型
                }
            } else {
                if (realObjs[i] instanceof String) {
                    if (inValuesType != String.class) {
                        throw new Exception("filter in 中數據的格式不一致:" + filter.getKey() + " " + filter.getOper() + " " + filter.getValue() + "$" + filter.getLogOper());
                    }
                } else if (realObjs[i] instanceof Date) {
                    if (inValuesType != Date.class) {
                        throw new Exception("filter in 中數據的格式不一致:" + filter.getKey() + " " + filter.getOper() + " " + filter.getValue() + "$" + filter.getLogOper());
                    }
                } else if (realObjs[i] instanceof Double) {
                    if (inValuesType != Double.class) {
                        throw new Exception("filter in 中數據的格式不一致:" + filter.getKey() + " " + filter.getOper() + " " + filter.getValue() + "$" + filter.getLogOper());
                    }
                } else {
                    throw new Exception("filter in 中數據的格式不對:" + filter.getKey() + " " + filter.getOper() + " " + filter.getValue() + "$" + filter.getLogOper());//根本不是 日期類型
                }
            }
        }

        String filterKey = filter.getKey();
        Type finalInValuesType = inValuesType;

        Predicate<Map<String, Object>> result = map -> {
            if (ObjectUtil.isEmpty(map.get(filterKey))) {
                return false; //該字段不存在。
            }
            if (finalInValuesType == String.class) {
                String targetObj = map.get(filterKey).toString();
                val collect = Arrays.stream(realObjs).map(o -> (String) o).collect(Collectors.toList());
                return collect.contains(targetObj);
            } else if (finalInValuesType == Date.class) {
                String targetObjStr = map.get(filterKey).toString();
                Date targetObj;
                try {
                    targetObj = getDateFromString(targetObjStr);
                } catch (Exception e) {
                    throw new ParamHandlerException("filter in 原始數據格式不匹配 日期類型 轉換失敗:" + targetObjStr + "|" + e.getMessage());//根本不是 日期類型
                }
                val collect = Arrays.stream(realObjs).map(o -> (Date) o).collect(Collectors.toList());
                return collect.contains(targetObj);
            } else if (finalInValuesType == Double.class) {
                double targetObj;
                try {
                    targetObj = Double.parseDouble(map.get(filterKey).toString());
                } catch (Exception e) {
                    throw new ParamHandlerException("filter in 格式有誤 數字類型 轉換失敗:" + map.get(filterKey).toString() + "|" + e.getMessage());//根本不是 數字類型
                }
                val collect = Arrays.stream(realObjs).map(o -> (Double) o).collect(Collectors.toList());
                return collect.contains(targetObj);
            }
            return false; /*else {
                throw new ParamHandlerException("filter in 中 finalInValuesType 數據的格式不對:" + finalInValuesType.getTypeName());//not need infect
            }*/
        };
        AssertUtils.notNull(result, "filter 輸入有誤 NULL IN");
        return result;
    }

    public static Predicate<Map<String, Object>> getCmpPredicate(FilterModel filter) {
        Object realObjectValue = getRealObjectValueFromSourceStr(filter.getValue());
        String filterKey = filter.getKey();
        return getMapPredicate(filter, filterKey, realObjectValue);
    }

    public static Predicate<Map<String, Object>> getMapPredicate(FilterModel filter, String filterKey, Object realObjectValue) {
        Predicate<Map<String, Object>> result;
        switch (filter.getOper()) {
            case "=":
                result = getPredicate(filter, filterKey, realObjectValue, i -> i == 0);
                break;
            case "<>":
                result = getPredicate(filter, filterKey, realObjectValue, i -> i != 0);
                break;
            case ">=":
                result = getPredicate(filter, filterKey, realObjectValue, i -> i >= 0);
                break;
            case ">":
                result = getPredicate(filter, filterKey, realObjectValue, i -> i > 0);
                break;
            case "<=":
                result = getPredicate(filter, filterKey, realObjectValue, i -> i <= 0);
                break;
            case "<":
                result = getPredicate(filter, filterKey, realObjectValue, i -> i < 0);
                break;
            default:
                throw new ParamHandlerException("filter 格式有誤 :" + filter.getKey() + " " + filter.getOper() + " " + filter.getValue() + "$" + filter.getLogOper());
        }
        return result;
    }

    public static Predicate<Map<String, Object>> getPredicate(FilterModel filter, String filterKey, Object realObjectValue, Predicate<Integer> p) {
        Predicate<Map<String, Object>> result;
        if (realObjectValue instanceof String) {
            String o = (String) realObjectValue;
            result = map -> ObjectUtil.notEmpty(map.get(filterKey)) && p.test(map.get(filterKey).toString().compareTo(o));
        } else if (realObjectValue instanceof Date) {
            Date o = (Date) realObjectValue;
            result = map -> {
                if (ObjectUtil.isEmpty(map.get(filterKey))) {
                    return false; //該字段不存在。
                }
                String dateStr = map.get(filterKey).toString();
                Date targetDate;
                try {
                    targetDate = getDateFromString(dateStr);
                } catch (Exception e) {
                    throw new ParamHandlerException("原始數據的格式 與 filter 給定不匹配 不是 日期類型:" + dateStr + "|" + e.getMessage());//根本不是 日期類型
                }
                return p.test(targetDate.compareTo(o));
            };
        } else if (realObjectValue instanceof Double) {
            Double o = (Double) realObjectValue;
            result = map -> {
                if (ObjectUtil.isEmpty(map.get(filterKey))) {
                    return false; //該字段不存在。
                }
                String sDouble = map.get(filterKey).toString();
                Double v;
                try {
                    v = Double.parseDouble(sDouble);
                } catch (Exception e) {
                    throw new ParamHandlerException("原始數據的格式 與 filter 給定不匹配 不是 數字類型:" + sDouble + "|" + e.getMessage());//根本不是 日期類型
                }
                return p.test(v.compareTo(o));
            };
        } else {
            throw new ParamHandlerException("filter 格式有誤 date :" + filter.getKey() + " " + filter.getOper() + " " + filter.getValue() + "$" + filter.getLogOper());
        }
        return result;
    }

    public static Object getRealObjectValueFromSourceStr(String sourceStr) {
        if (StringUtils.isEmpty(sourceStr)) {
            throw new ParamHandlerException("filter 格式有誤 empty(字符串,日期,數字)" + sourceStr);//根本不是 3者類型
        }
        if (sourceStr.startsWith("\"") && sourceStr.endsWith("\"")) {// 字符串類型
            return sourceStr.substring(1, sourceStr.length() - 1);
        } else if (sourceStr.startsWith("'") && sourceStr.endsWith("'")) {// 日期類型
            String filterValueStr = sourceStr.substring(1, sourceStr.length() - 1);
            try {
                return getDateFromString(filterValueStr);
            } catch (Exception e) {
                throw new ParamHandlerException("filter 格式有誤 日期類型 轉換失敗:" + sourceStr + "|" + e.getMessage());//根本不是 日期類型
            }
        } else {// 數字類型
            try {
                return Double.parseDouble(sourceStr);
            } catch (Exception e) {
                throw new ParamHandlerException("filter 格式有誤 數字類型 轉換失敗:" + sourceStr + "|" + e.getMessage());//根本不是 數字類型
            }
        }
    }

    private static Date getDateFromString(String src) throws Exception {
        Date filterDate;
        if (patternYMD.matcher(src).matches()) {
            filterDate = sdfYMD.parse(src);
        } else if (patternFull.matcher(src).matches()) {
            filterDate = sdfFull.parse(src);
        } else if (patternHms.matcher(src).matches()) {
            filterDate = sdfHms.parse(src);// not need infect
        } else {
            throw new Exception("filter 格式有誤 根本不是 日期類型:" + src);//根本不是 日期類型
        }
        return filterDate;
    }



}

 

 Comparator<Map<String, Object>> cmp = null;            for (int i = 0; i < st.size(); i++) {                String t = st.get(i);                String r = sr.get(i);                Comparator<Map<String, Object>> thiscmp = (m1, m2) -> {                    if (r.equalsIgnoreCase("1")) {//正序                        if (m1.get(t) == null && m2.get(t) == null) {                            return 0;                        } else if (m1.get(t) == null) {                            return -1;                        } else if (m2.get(t) == null) {                            return 1;                        } else {                            return m1.get(t).toString().compareTo(m2.get(t).toString());                        }                    } else if (r.equalsIgnoreCase("-1")) {////逆序                        if (m1.get(t) == null && m2.get(t) == null) {                            return 0;                        } else if (m1.get(t) == null) {                            return 1;                        } else if (m2.get(t) == null) {                            return -1;                        } else {                            return -m1.get(t).toString().compareTo(m2.get(t).toString());                        }                    }                    return 0;                };                if (cmp == null) {                    cmp = thiscmp;                } else {                    cmp = cmp.thenComparing(thiscmp);                }            }            if (cmp != null) {                datas.sort(cmp);            }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章