动态生成多字段排序,动态生成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<Map<String, Object>> 按照自定义 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); }