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