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"));
}
}