JEXL表达式计算,支持自定义函数
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
public class JexlTest {
public static void main(String[] args) {
{
String content = "abs(x-y)";
Map<String, Number> map = new HashMap<>();
map.put("x", new BigDecimal("0.9"));
map.put("y", new BigDecimal("1"));
Object result = JexlTools.evaluate(content, map);
System.out.println(content + " = " + result);
}
{
String content = "cos(pi)";
Map<String, Number> map = new HashMap<>();
map.put("pi", BigDecimal.valueOf(Math.PI));
Object result = JexlTools.evaluate(content, map);
System.out.println(content + " = " + result);
}
{
String content = "sum(x, -y)";
Map<String, Number> map = new HashMap<>();
map.put("x", new BigDecimal("0.9"));
map.put("y", new BigDecimal("1"));
Object result = JexlTools.evaluate(content, map);
System.out.println(content + " = " + result);
}
{
String content = "sum(x, y, z)";
Map<String, Number> map = new HashMap<>();
map.put("x", new BigDecimal("0.9"));
map.put("y", new BigDecimal("0.8"));
map.put("z", new BigDecimal("0.7"));
Object result = JexlTools.evaluate(content, map);
System.out.println(content + " = " + result);
}
}
}
JexlTools
在JexlMath增加方法即可扩展自定义函数
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.jexl3.JexlBuilder;
import org.apache.commons.jexl3.JexlContext;
import org.apache.commons.jexl3.JexlEngine;
import org.apache.commons.jexl3.JexlExpression;
import org.apache.commons.jexl3.MapContext;
/**
* JEXL工具类
*
* @author zhaohuihua
* @version 20210414
*/
public class JexlTools {
/**
* 自定义数学函数 (在这里增加方法即可扩展自定义函数)
*
* @author zhaohuihua
* @version 20210414
*/
public static class JexlMath {
public BigDecimal sin(BigDecimal x) {
return BigDecimal.valueOf(Math.sin(x.doubleValue()));
}
public BigDecimal cos(BigDecimal x) {
return BigDecimal.valueOf(Math.cos(x.doubleValue()));
}
public BigDecimal abs(BigDecimal x) {
return x.compareTo(BigDecimal.ZERO) >= 0 ? x : BigDecimal.ZERO.subtract(x);
}
public BigDecimal sum(BigDecimal x, BigDecimal y) {
return x.add(y);
}
public BigDecimal sum(BigDecimal x, BigDecimal y, BigDecimal z) {
return x.add(y).add(z);
}
}
/**
* 计算表达式
*
* @param expression 表达式
* @param vars 变量值
* @return 计算结果
*/
public static Object evaluate(String expression, Map<String, ?> vars) {
JexlContext context = new MapContext();
for (Entry<String, ?> entry : vars.entrySet()) {
Object value = entry.getValue();
if (value instanceof Number) {
context.set(entry.getKey(), BigDecimal.valueOf(((Number) value).doubleValue()));
} else {
context.set(entry.getKey(), value);
}
}
JexlExpression e = jexl.createExpression(expression);
return e.evaluate(context);
}
private static JexlEngine jexl;
static {
Map<String, Object> funcs = new HashMap<String, Object>();
funcs.put(null, new JexlMath());
jexl = new JexlBuilder().namespaces(funcs).create();
}
}
2.1.1版本的写法,JexlExpression要改为Expression
private static JexlEngine jexl;
static {
Map<String, Object> funcs = new HashMap<String, Object>();
funcs.put(null, new JexlMath());
jexl = new JexlEngine();
jexl.setFunctions(funcs);
}