JEXL表达式计算,支持自定义函数

    1. import java.math.BigDecimal;
    2. import java.util.HashMap;
    3. import java.util.Map;
    4. public class JexlTest {
    5. public static void main(String[] args) {
    6. {
    7. String content = "abs(x-y)";
    8. Map<String, Number> map = new HashMap<>();
    9. map.put("x", new BigDecimal("0.9"));
    10. map.put("y", new BigDecimal("1"));
    11. Object result = JexlTools.evaluate(content, map);
    12. System.out.println(content + " = " + result);
    13. }
    14. {
    15. String content = "cos(pi)";
    16. Map<String, Number> map = new HashMap<>();
    17. map.put("pi", BigDecimal.valueOf(Math.PI));
    18. Object result = JexlTools.evaluate(content, map);
    19. System.out.println(content + " = " + result);
    20. }
    21. {
    22. String content = "sum(x, -y)";
    23. Map<String, Number> map = new HashMap<>();
    24. map.put("x", new BigDecimal("0.9"));
    25. map.put("y", new BigDecimal("1"));
    26. Object result = JexlTools.evaluate(content, map);
    27. System.out.println(content + " = " + result);
    28. }
    29. {
    30. String content = "sum(x, y, z)";
    31. Map<String, Number> map = new HashMap<>();
    32. map.put("x", new BigDecimal("0.9"));
    33. map.put("y", new BigDecimal("0.8"));
    34. map.put("z", new BigDecimal("0.7"));
    35. Object result = JexlTools.evaluate(content, map);
    36. System.out.println(content + " = " + result);
    37. }
    38. }
    39. }

    JexlTools
    在JexlMath增加方法即可扩展自定义函数

    1. import java.math.BigDecimal;
    2. import java.util.HashMap;
    3. import java.util.Map;
    4. import java.util.Map.Entry;
    5. import org.apache.commons.jexl3.JexlBuilder;
    6. import org.apache.commons.jexl3.JexlContext;
    7. import org.apache.commons.jexl3.JexlEngine;
    8. import org.apache.commons.jexl3.JexlExpression;
    9. import org.apache.commons.jexl3.MapContext;
    10. /**
    11. * JEXL工具类
    12. *
    13. * @author zhaohuihua
    14. * @version 20210414
    15. */
    16. public class JexlTools {
    17. /**
    18. * 自定义数学函数 (在这里增加方法即可扩展自定义函数)
    19. *
    20. * @author zhaohuihua
    21. * @version 20210414
    22. */
    23. public static class JexlMath {
    24. public BigDecimal sin(BigDecimal x) {
    25. return BigDecimal.valueOf(Math.sin(x.doubleValue()));
    26. }
    27. public BigDecimal cos(BigDecimal x) {
    28. return BigDecimal.valueOf(Math.cos(x.doubleValue()));
    29. }
    30. public BigDecimal abs(BigDecimal x) {
    31. return x.compareTo(BigDecimal.ZERO) >= 0 ? x : BigDecimal.ZERO.subtract(x);
    32. }
    33. public BigDecimal sum(BigDecimal x, BigDecimal y) {
    34. return x.add(y);
    35. }
    36. public BigDecimal sum(BigDecimal x, BigDecimal y, BigDecimal z) {
    37. return x.add(y).add(z);
    38. }
    39. }
    40. /**
    41. * 计算表达式
    42. *
    43. * @param expression 表达式
    44. * @param vars 变量值
    45. * @return 计算结果
    46. */
    47. public static Object evaluate(String expression, Map<String, ?> vars) {
    48. JexlContext context = new MapContext();
    49. for (Entry<String, ?> entry : vars.entrySet()) {
    50. Object value = entry.getValue();
    51. if (value instanceof Number) {
    52. context.set(entry.getKey(), BigDecimal.valueOf(((Number) value).doubleValue()));
    53. } else {
    54. context.set(entry.getKey(), value);
    55. }
    56. }
    57. JexlExpression e = jexl.createExpression(expression);
    58. return e.evaluate(context);
    59. }
    60. private static JexlEngine jexl;
    61. static {
    62. Map<String, Object> funcs = new HashMap<String, Object>();
    63. funcs.put(null, new JexlMath());
    64. jexl = new JexlBuilder().namespaces(funcs).create();
    65. }
    66. }

    2.1.1版本的写法,JexlExpression要改为Expression

    1. private static JexlEngine jexl;
    2. static {
    3. Map<String, Object> funcs = new HashMap<String, Object>();
    4. funcs.put(null, new JexlMath());
    5. jexl = new JexlEngine();
    6. jexl.setFunctions(funcs);
    7. }