jep3.5 java 动态公式
- 背景:
-
- 公司采集数据,有时候会对采集的数据进行一些公式计算。有很多家企业,各式各样的公式,如果在代码里写死就很傻了。采取了两种方案,一种是用模板,然后用js 脚本引擎计算,另外一种是引入 jep jar 包,很方便,下面就简单介绍一下使用,以及我的一个工具类
<!-- 计算表达式 -->
<dependency>
<groupId>com.liyang</groupId>
<artifactId>jep</artifactId>
<version>3.5</version>
</dependency>
package com.zj.common.utils;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.springframework.util.StringUtils;
import com.singularsys.jep.Jep;
import com.singularsys.jep.JepException;
import com.singularsys.jep.bigdecimal.BigDecComponents;
import com.singularsys.jep.parser.Node;
public class JepUtils {
public static void calc(LinkedHashMap<String, JepVO> jepMap, Map<String, BigDecimal> params) {
Jep jep = new Jep(new BigDecComponents((MathContext.DECIMAL32)));
try {
addParams(jep, params);
Node node = null;
Set<Entry<String, JepVO>> entrySet = jepMap.entrySet();
for (Entry<String, JepVO> entry : entrySet) {
BigDecimal result = entry.getValue().getResult();
if (!StringUtils.isEmpty(entry.getValue().getExpression())) {
node = jep.parse(entry.getValue().getExpression());
Object value = jep.evaluate(node);
if (value != null) {
if(value instanceof Boolean) {
result = (Boolean)value ? BigDecimal.ONE : BigDecimal.ZERO;
}else {
result = new BigDecimal(value.toString());
}
}
entry.getValue().setResult(result);
jep.addVariable(entry.getKey(), result);
}
}
} catch (JepException e) {
e.printStackTrace();
}
}
public static void addParams(Jep jep, Map<String, BigDecimal> map) {
Set<Entry<String, BigDecimal>> entrySet = map.entrySet();
for (Entry<String, BigDecimal> entry : entrySet) {
try {
jep.addVariable(entry.getKey(), entry.getValue());
} catch (JepException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Map<String, BigDecimal> params = new HashMap<>();
params.put("x", BigDecimal.ONE);
params.put("k2", new BigDecimal(9999.00));
LinkedHashMap<String, JepVO> map = new LinkedHashMap<>();
map.put("x", new JepVO("k2>0", new BigDecimal(0)));
map.put("k2", new JepVO("k2*x", new BigDecimal(0)));
calc(map, params);
System.out.println(map);
}
}
package com.zj.common.utils;
import java.math.BigDecimal;
import lombok.ToString;
@ToString
public class JepVO {
private String expression;
private BigDecimal result = new BigDecimal(0);
public JepVO(String expression, BigDecimal result) {
super();
this.expression = expression;
this.result = result;
}
public String getExpression() {
return expression;
}
public void setExpression(String expression) {
this.expression = expression;
}
public BigDecimal getResult() {
return result;
}
public void setResult(BigDecimal result) {
this.result = result;
}
}