Java动态计算
公式的解析和参数设置.有两个选择 . 一个是引用apache下的commons-jexl包.用其中的包装好的方法 . 一个是用jdk中原生的scriptEngine引擎实现 .
一 . commons-jexl包使用
pom包引用
1 2 3 4 5 | <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-jexl3</artifactId> <version> 3.1 </version> </dependency> |
工具方法如下 :
/** * jexlEngine引擎执行公式计算 * @param jexExp 公式 . 如 (a+b-c)*d/f * @param reflectParamMap 参数集合 * @return 返回结果默认String * @throws Throwable */ public static String calWithJexlEngine(String jexExp , Map<String , Object> reflectParamMap) throws Throwable{ JexlEngine engine = new Engine(); JexlExpression expression = engine.createExpression(jexExp); JexlContext jc = new MapContext(); reflectParamMap.keySet().forEach(k->{ //jexl计算结果类型根据入参决定: //如果参数都是int/Integer类型 . 那么即便结果值应该是4.8 . 返回值也是4 .所以这里为保证计算精度 . 入参可全部以decimal类型处理下 //若参数中存在小数,则结果精度相对准确 . 出参为double类型 Object paramVal = reflectParamMap.get(k); String paramValStr = paramVal != null ? String.valueOf(paramVal) : "0"; jc.set(k , new BigDecimal(paramValStr)); }); Object result =expression.evaluate(jc); DecimalFormat decimalFormat = new DecimalFormat("0.00"); return decimalFormat.format(result); }
二.jdk中scriptEngine引擎执行计算
/** * jdk的ScriptEngine引擎执行公式计算 * @param jexExp 公式 . 如 (a+b-c)*d/f 或者是带判断的函数表达式 : if(a == 1) b*(c+2)/d; * @param reflectParamMap 参数集合 * @param paramScope 参数范围 * @return */ public static String calWithScriptEngine(String jexExp , Map<String , Object> reflectParamMap , Integer paramScope) throws Throwable{ ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("js"); Bindings bindings = scriptEngine.createBindings(); bindings.putAll(reflectParamMap); paramScope = paramScope != null ? paramScope : ScriptContext.ENGINE_SCOPE; scriptEngine.setBindings(bindings , paramScope); //出参默认为double类型的 . 入参类型对结果精度无影响 Object result = scriptEngine.eval(jexExp); //保留两位小数 DecimalFormat decimalFormat = new DecimalFormat("0.00"); return decimalFormat.format(result); }
调用示例
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!