Jep的初探

Jep的简单使用(解析和评估数学表达式)

Jep Java 只需几行代码就可以解析和评估数学表达式。该软件包允许您的用户以字符串形式输入公式,并立即对其进行评估。Jep 支持用户定义的变量、常量和函数。包括许多常见的数学函数和常数。

最近在做项目的时候多处使用到了数学表达式的计算,故寻找了一个比较有意思的工具类,方便的实现了对表达式的封装。

@SpringBootTest
class MyWebApplicationTests {


    @Test
    void contextLoads() throws Exception {
        UserModel userModel = new UserModel();
        UserModel userModel1 = userModel.builder().age(18).id(1L).build();
        String exp = "(age * (age + 10))/age";
        Object resultAdvanced = MathFormulaUtil.getResultAdvanced(userModel1, exp);
        System.out.println(resultAdvanced);
    }

}

class MathFormulaUtil {

    /** * GET 新技能 * @param obj 目标对象 里面封装了数据 * @param exp 表达式 * @return 计算结果 * @throws Exception 异常 */
    @SuppressWarnings({"rawtypes"})
    public static Object getResultAdvanced(Object obj,String exp) throws Exception{
        Object result = null; //算术结果
        try {
            //核心对象
            JEP jep = new JEP();
            //获取目标对象的 属性名 和 属性值组成的Map对象,然后Map对象组成List
            List fieldsLists = getFiledsInfo(obj);
            //循环一次取出 List 中的 Map 中的 key - value
            for (Object listObj : fieldsLists) {
                //获取属性名称
                String fieldName = String.valueOf(((Map) listObj).get("name"));
                //获取属性的值
                Object fieldValue = getFieldValueByName(fieldName, obj);
                if(fieldValue != null && !fieldValue.toString().isEmpty()){ //保证非空
                    //添加变量 动态赋值
                    jep.addVariable(fieldName, Double.parseDouble(String.valueOf(fieldValue)));
                }
            }
            //解析
            jep.parseExpression(exp);
            //计算结果
            result = jep.getValue();
        } catch (Exception e) {
            System.err.println("表达式中所含的字段 在实体类中没有赋予相应的值");
        }
        //返回结果
        return result;
    }

    /** * 根据属性名获取属性值 * @param fieldName 变量名 * @param o 对象 * @throws Exception 异常 * * @author 杨润康 * */
    private static Object getFieldValueByName(String fieldName, Object o) throws Exception {
        //构造get方法名
        String getter = "get" + firstAlpUpCase(fieldName);
        //获取方法
        Method method = o.getClass().getMethod(getter, new Class[] {});
        //取值
        Object value = method.invoke(o, new Object[] {});

        return value;
    }


    /**
     *
     * 获取 属性名(name),属性值(value)的map组成的list
     * @param 目标对象
     * @return 封装了 属性-值 的Map 组成的 List 集合
     * @throws Exception 异常
     *
     * @author 杨润康
     *
     */
    @SuppressWarnings({ "unused", "rawtypes", "unchecked" })
    private static List getFiledsInfo(Object o) throws Exception{
        //获取定义的变量
        Field[] fields=o.getClass().getDeclaredFields();
        //变量名数组
        String[] fieldNames=new String[fields.length];
        List list = new ArrayList();
        Map infoMap=null;
        for(int i=0;i<fields.length;i++){
            if (Modifier.isStatic(fields[i].getModifiers())) {
                continue;
            }
            infoMap = new HashMap();
            //获取变量名
            infoMap.put("name", fields[i].getName());
            //变量名对应的值
            infoMap.put("value", getFieldValueByName(fields[i].getName(), o));
            //存入集合
            list.add(infoMap);
        }
        return list;
    }

    /** * 字符串首字母大写 * @param nodeName 节点名称 * @return 首字母大写的字符串 * * @author 杨润康 */
    public static String firstAlpUpCase(String nodeName) {
        String s = nodeName.substring(0,1);
        Pattern p = Pattern.compile("[a-z]");
        Matcher m = p.matcher(s);
        if(m.matches()){
            char[] cs=nodeName.toCharArray();
            cs[0]-=32;
            return String.valueOf(cs);
        }
        return nodeName;
    }

}
注意事项

如果使用了lombok,大家都清楚lombok boolean类型的参数存在序列化的问题,故在定义boolean类型的时候使用Boolean引用数据类型来定义

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值