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