当前位置: 首页 > 工具软件 > Tulip > 使用案例 >

用JEP+SpringBoot进行动态公式处理计算

傅阿苏
2023-12-01

jep
JEP是Java expression parser的简称,即java表达式分析器,Jep是一个用来转换和计算数学表达式的java库。通过这个程序包,用户可以以字符串的形式输入一个、任意的公式,然后快速地计算出结果。Jep支持用户自定义变量、常量和函数。包括许多常用的数学函数和常。

一、在pom文件中引jep的jar包:
 

<!-- https://mvnrepository.com/artifact/org.scijava/jep -->
        <dependency>
            <groupId>org.scijava</groupId>
            <artifactId>jep</artifactId>
            <version>2.4.2</version>
        </dependency>

二、工具类

 直接上代码

/**
 * @description: 数学公式解析计算
 * @author: jxq
 * @date: 2021/3/25 12:44 下午
 * @version: 1.0
 **/
public class ExpressionUtil {

    /**
     * 动态配置公式方式
     *
     * @param mapList
     * @param conditionExpr
     * @param formulaExpr
     * @param evaluate
     */
    public static void workOutListMap(List<Map> mapList, String conditionExpr, String formulaExpr, String evaluate) {
        for (Map map : mapList) {
            JEP jep = getJEP(map);
            workOutKey(jep, map, conditionExpr, formulaExpr, evaluate);
        }
    }

    /**
     * 动态配置公式方式
     *
     * @param map
     * @param conditionExpr
     * @param formulaExpr
     * @param evaluate
     */
    public static void workOutMap(Map map, String conditionExpr, String formulaExpr, String evaluate) {
        JEP jep = getJEP(map);
        workOutKey(jep, map, conditionExpr, formulaExpr, evaluate);
    }


    /**
     * 计算出表达式并填充
     *
     * @param jep
     * @param map
     * @param conditionExpr
     * @param formulaExpr
     * @param evaluate
     */
    private static void workOutKey(JEP jep, Map map, String conditionExpr, String formulaExpr, String evaluate) {
        //如果没有条件
        if (StringUtil.isEmpty(conditionExpr)) {
            map.put(evaluate, workOutSingle(jep, formulaExpr));
            //如果有条件 且条件为true
        } else if (workOutBool(jep, conditionExpr)) {
            map.put(evaluate, workOutSingle(jep, formulaExpr));
        }
    }

    /**
     * 判断条件表达式
     *
     * @param jep
     * @param expression
     * @return
     */
    private static boolean workOutBool(JEP jep, String expression) {
        return (Double) workOutSingle(jep, expression) > 0;
    }

    /**
     * 计算表达式的值
     *
     * @param jep
     * @param expression
     * @return
     */
    private static Object workOutSingle(JEP jep, String expression) {
        Object result = null;
        try { //执行
            Node parse = jep.parse(expression);
            result = jep.evaluate(parse);
        } catch (ParseException e) {
            throw new MyException(101, "公式表达式解析失败");
        }
        if (result == null) {
            throw new MyException(101, "公式表达式解析失败");
        }
        return result;
    }

    /**
     * 获取填充好变量的JEP对象
     *
     * @param param
     * @return
     */
    private static JEP getJEP(Map param) {
        JEP jep = new JEP();
        Set<Map.Entry> set = param.entrySet();
        for (Map.Entry entry : set) {
            Object entryValue = entry.getValue();
            String entryKey = (String) entry.getKey();
            jep.addVariable(entryKey, entryValue);
        }
        return jep;
    }
}

三、main方法测试一下

 

public static void main(String[] args) {
        List<Map> mapList = new ArrayList<>();
        Map map = new HashMap() {{
            put("a", 4);
            put("b", 0);
            put("c", 3);
        }};
        Map map2 = new HashMap() {{
            put("a", 4);
            put("b", 0);
            put("c", 3);
        }};
        Map map3 = new HashMap() {{
            put("ecpm", 400);
            put("n", 1);
            put("c", 3);
        }};
        mapList.add(map);
        mapList.add(map2);
        ExpressionUtil.workOutListMap(mapList, "a > 3 && b > 1", "a+b+c * 2", "res");
        ExpressionUtil.workOutListMap(mapList, "a > 3 && b < 1", "a+b+c * 3", "res");
        ExpressionUtil.workOutListMap(mapList, "a < 0", "a+b+c", "res");
        ExpressionUtil.workOutMap(map3, "n <= 3", "ecpm * (4.5 - 0.5 * n)", "res");
        System.out.println(map3.get("res"));
        for (Map m : mapList) {
            System.out.println(m.get("res"));
        }
    }

 

 类似资料: