AVIATOR—轻量级JAVA表达式求值引擎

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.Options;
import com.common.util.ExpressionUtil;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.Map;

public class CapitalUtil {

    public static boolean isNumeric(String str) {
        return str.matches("-?[0-9]+.?[0-9]*");
    }

    static {
        // 将表达式中的浮点数&整型数字都解析为 BigDecimal,默认为 false;仅支持表达式中的浮点数&整型数字,传入的参数不会转换为BigDecimal
//        AviatorEvaluator.setOption(Options.ALWAYS_PARSE_FLOATING_POINT_NUMBER_INTO_DECIMAL, true);
//        AviatorEvaluator.setOption(Options.ALWAYS_PARSE_INTEGRAL_NUMBER_INTO_DECIMAL, true);

//        AviatorEvaluator.setOption(Options.MATH_CONTEXT, MathContext.DECIMAL64);
    }

    public static void main(String[] args) {
        String str = "1";
        System.out.println("isNumeric() = " + isNumeric(str) + ", ==> "+ Double.valueOf(str));
        str = "15454888";
        System.out.println("isNumeric() = " + isNumeric(str) + ", ==> "+ Double.valueOf(str));
        str = "01.212001";
        System.out.println("isNumeric() = " + isNumeric(str) + ", ==> "+ Double.valueOf(str));
        str = "-1";
        System.out.println("isNumeric() = " + isNumeric(str) + ", ==> "+ Double.valueOf(str));
        str = "-1554";
        System.out.println("isNumeric() = " + isNumeric(str) + ", ==> "+ Double.valueOf(str));
        str = "-03.2120010";
        System.out.println("isNumeric() = " + isNumeric(str) + ", ==> "+ Double.valueOf(str));
        str = "-s03.2120010";
        System.out.println("isNumeric() = " + isNumeric(str) + ", ==> "+ str);
        str = "03.2120s10";
        System.out.println("isNumeric() = " + isNumeric(str) + ", ==> "+ str);

        Map<String, Object> mapParam = Maps.newHashMap();
        mapParam.put("a", new BigDecimal(400));
        mapParam.put("b", new BigDecimal(400));
        mapParam.put("c", new BigDecimal(500));
        mapParam.put("参数1", new BigDecimal("7"));
        mapParam.put("参数2", new BigDecimal("3"));
        mapParam.put("param3", new BigDecimal("3"));

        boolean result = ExpressionUtil.verify("a > 300 && a<500", mapParam);
        System.out.println("ExpressionUtil.verify(a > 300 && a<500),   400 = " + result);

        mapParam.put("a", new BigDecimal(600));
        result = ExpressionUtil.verify("a > 300 && a <500", mapParam);
        System.out.println("ExpressionUtil.verify(a > 300 && a<500),   600 = " + result);

        result = ExpressionUtil.verify("a > 300 && b<500 && c < 600", mapParam);
        System.out.println("ExpressionUtil.verify(a > 300 && b<500 && c < 600),  400,400,500 = " + result);

        mapParam.put("c", new BigDecimal(700));
        result = ExpressionUtil.verify(" (a > 300 && b<500) || c < 600", mapParam);
        System.out.println("a > 300 && b<500 && c < 600),  400,400,700 = " + result);


        BigDecimal totalBD = ExpressionUtil.calculate("a + 123.2", mapParam);
        System.out.println("totalBD = " + totalBD);

        mapParam.put("a", new BigDecimal("0.1"));
        mapParam.put("b", new BigDecimal("0.2"));
        BigDecimal totalBD2 = ExpressionUtil.calculate("a + b", mapParam);
        System.out.println("totalBD2 = " + totalBD2);

        mapParam.put("c", new BigDecimal("3"));
        totalBD2 = ExpressionUtil.calculate("(a + b )* c", mapParam);
        System.out.println("totalBD2 = " + totalBD2);

        totalBD2 = ExpressionUtil.calculate(" (参数1 + 参数2 )   / param3", mapParam);
        System.out.println("totalBD2 = " + totalBD2);
        System.out.println("totalBD2 = " + totalBD2.setScale(2, RoundingMode.HALF_UP));

        totalBD2 = ExpressionUtil.calculate(" (参数1 + ( b * c/a+参数2) )   / param3", mapParam);
        System.out.println("totalBD2 = " + totalBD2);
        System.out.println("totalBD2 = " + totalBD2.setScale(2, RoundingMode.HALF_UP));
        System.out.println("---------------------------");

        double v = 0.05 + 0.01;
        System.out.println(v);      // 0.060000000000000005
        double v1 = 1.0 - 0.42;
        System.out.println(v1);     // 0.5800000000000001
        double v2 = 4.015 * 100;
        System.out.println(v2);     // 401.49999999999994
        double v3 = 123.3 / 100;
        System.out.println(v3);     // 1.2329999999999999

        mapParam.put("a", 0.05);
        mapParam.put("b", 0.01);
        Object res = AviatorEvaluator.execute("a +b", mapParam, true);
        System.out.println("a + b = " + res +", class =" + res.getClass());   // a + b = 0.060000000000000005, class =class java.lang.Double

        res = AviatorEvaluator.execute("0.05 +0.01", mapParam, true);
        System.out.println("res2 = " + res +", class =" + res.getClass());  // res2 = 0.06, class =class java.math.BigDecimal

        mapParam.put("a", new BigDecimal(1.0));
        mapParam.put("b", new BigDecimal(0.42));
        res = AviatorEvaluator.execute(" a-b", mapParam, true);
        System.out.println("a - b = " + res +", class =" + res.getClass());   // a - b = 0.5800000000000000155431223447521916, class =class java.math.BigDecimal

        AviatorEvaluator.setOption(Options.MATH_CONTEXT, MathContext.DECIMAL64);
        mapParam.put("a", new BigDecimal(1.0));
        mapParam.put("b", new BigDecimal(0.42));
        res = AviatorEvaluator.execute(" a-b", mapParam, true);
        System.out.println("a - b = " + res +", class =" + res.getClass());   // a - b = 0.5800000000000000, class =class java.math.BigDecimal

        mapParam.put("a", new BigDecimal("4.015"));
        mapParam.put("b", new BigDecimal("100"));
        res = ExpressionUtil.aviatorEvaluator.compile("a*b", true).execute(mapParam);;
        System.out.println("a * b = " + res +", class =" + res.getClass());   // a * b = 401.500, class =class java.math.BigDecimal

        mapParam.put("a", new BigDecimal("123.3"));
        mapParam.put("b", new BigDecimal("100"));
        res = AviatorEvaluator.execute(" a/b", mapParam, true);
        System.out.println("a / b = " + res +", class =" + res.getClass());   // a / b = 1.233, class =class java.math.BigDecimal

        System.out.println("---------------------------");
        System.out.println("totalBD2 = " + new BigDecimal("3.334").setScale(2, RoundingMode.HALF_UP));
        System.out.println("totalBD2 = " + new BigDecimal("3.335").setScale(2, RoundingMode.HALF_UP));
        System.out.println("totalBD2 = " + new BigDecimal("3.336").setScale(2, RoundingMode.HALF_UP));
        System.out.println("---------------------------");

        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            totalBD2 = ExpressionUtil.calculate(" (参数1 + 参数2 )   / param3", ImmutableMap.of("参数1", new BigDecimal(i),
                    "参数2", new BigDecimal("3"), "param3", new BigDecimal("3")));
//            System.out.println("execute = " + totalBD2);
        }
        System.out.println("耗时 = " + (System.currentTimeMillis() - start));

        start = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            totalBD2 = (BigDecimal) AviatorEvaluator.execute(" (参数1 + 参数2 )   / param3", ImmutableMap.of("参数1", new BigDecimal(i),
                    "参数2", new BigDecimal("3"), "param3", new BigDecimal("3")), true);
//            System.out.println("execute = " + totalBD2);
        }
        System.out.println("耗时 = " + (System.currentTimeMillis() - start));

        // Compile a script
        ExpressionUtil.calculate("println('Hello, AviatorScript!!!')",null);



    }
}

 控制台打印:

isNumeric() = true, ==> 1.0
isNumeric() = true, ==> 1.5454888E7
isNumeric() = true, ==> 1.212001
isNumeric() = true, ==> -1.0
isNumeric() = true, ==> -1554.0
isNumeric() = true, ==> -3.212001
isNumeric() = false, ==> -s03.2120010
isNumeric() = false, ==> 03.2120s10
ExpressionUtil.verify(a > 300 && a<500),   400 = true
ExpressionUtil.verify(a > 300 && a<500),   600 = false
ExpressionUtil.verify(a > 300 && b<500 && c < 600),  400,400,500 = true
a > 300 && b<500 && c < 600),  400,400,700 = true
totalBD = 723.2
totalBD2 = 0.3
totalBD2 = 0.9
totalBD2 = 3.333333333333333333333333333333333
totalBD2 = 3.33
totalBD2 = 5.333333333333333333333333333333333
totalBD2 = 5.33
---------------------------
0.060000000000000005
0.5800000000000001
401.49999999999994
1.2329999999999999
a + b = 0.060000000000000005, class =class java.lang.Double
res2 = 0.06, class =class java.math.BigDecimal
a - b = 0.5800000000000000155431223447521916, class =class java.math.BigDecimal
a - b = 0.5800000000000000, class =class java.math.BigDecimal
a * b = 401.500, class =class java.math.BigDecimal
a / b = 1.233, class =class java.math.BigDecimal
---------------------------
totalBD2 = 3.33
totalBD2 = 3.34
totalBD2 = 3.34
---------------------------
耗时 = 114
耗时 = 21
Hello, AviatorScript!!!

import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.AviatorEvaluatorInstance;
import com.googlecode.aviator.Options;

import java.math.BigDecimal;
import java.util.Map;

public class ExpressionUtil {

    public static AviatorEvaluatorInstance aviatorEvaluator = AviatorEvaluator.getInstance();

    static {
        aviatorEvaluator.setOption(Options.ALWAYS_PARSE_FLOATING_POINT_NUMBER_INTO_DECIMAL, true);
//        aviatorEvaluator.setOption(Options.MATH_CONTEXT, MathContext.DECIMAL64);
    }

    /**
     * 表达式验证
     **/
    public static Boolean verify(String expression, Map<String, Object> params) {
        return (Boolean) aviatorEvaluator.compile(expression, true).execute(params);
    }

    /**
     * 表达式计算
     *
     * @param expression 表达式
     * @param params     需要替换的表达式参数
     * @return calculate result
     */
    public static BigDecimal calculate(String expression, Map<String, Object> params) {
        return (BigDecimal) aviatorEvaluator.compile(expression, true).execute(params);
    }
}

        <dependency>
            <groupId>com.googlecode.aviator</groupId>
            <artifactId>aviator</artifactId>
            <version>5.3.0</version>
        </dependency>

最终使用结果:

   static {
        AviatorEvaluator.setOption(Options.ALWAYS_PARSE_FLOATING_POINT_NUMBER_INTO_DECIMAL, true);
        AviatorEvaluator.setOption(Options.ALWAYS_PARSE_INTEGRAL_NUMBER_INTO_DECIMAL, true);
        AviatorEvaluator.setOption(Options.MATH_CONTEXT, MathContext.DECIMAL64);
    }

    public static boolean isNumeric(String str) {
        return str.matches("-?[0-9]+.?[0-9]*");
    }

    public static void main(String[] args) {
        Map<String, Object> mapParam = Maps.newHashMap();
        mapParam.put("a", new BigDecimal("400"));
        mapParam.put("b", new BigDecimal("400"));
        mapParam.put("c", new BigDecimal("500"));
        mapParam.put("参数1", new BigDecimal("7"));
        mapParam.put("参数2", new BigDecimal("3"));

        Object result = AviatorEvaluator.execute(" (a + b )* 参数2", mapParam, true);
        System.out.println("result = " + result);
    }

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嘿丶小伙计

请赏我点铜板买喵粮自己吃,谢谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值