Aviator计算引擎 | 您所在的位置:网站首页 › java自定义运算符 › Aviator计算引擎 |
[toc] 概述Aviator是一个开源的Java表达式求值器,不仅支持四则运算、三元运算、逻辑运算,而且其强大的接口支持自定义扩展函数。鉴于此,我原先的研发团队结合公司业务场景,选择了这个google的计算引擎,为了扩展我们业务需求,定义了一系列自定义函数,以支撑我们业务场景。 源代码 特性 数据类型 Number类型:数字类型,支持两种类型,分别对应Java的Long和Double,也就是说任何整数都将被转换为Long,而任何浮点数都将被转换 为Double,包括用户传入的数值也是如此转换。不支持科学计数法,仅支持十进制。如-1、100、2.3等。 String类型:字符串类型,单引号或者双引号括起来的文本串,如’helloworld’,变量如果传入的是String或者Character也将转为String类型。 Bool类型:常量true和false,表示真值和假值,与java的Boolean.TRUE和Boolean.False对应。 Pattern类型: 类似Ruby、perl的正则表达式,以//括起来的字符串,如/\d+/,内部实现为java.util.Pattern。 变量类型:与Java的变量命名规则相同,变量的值由用户传入,如"a"、"b"等 nil类型:常量nil,类似java中的null,但是nil比较特殊,nil不仅可以参与==、!=的比较,也可以参与>、>=、>” “>”。 匹配运算符匹配运算符"=~"用于String和Pattern的匹配,它的左操作数必须为String,右操作数必须为Pattern。匹配成功后,Pattern的分组将存于变量 $num,num为分组索引。 三元运算符Aviator没有提供if else语句,但是提供了三元运算符 “?:”,形式为 bool ? exp1: exp2。 其中bool必须为结果为Boolean类型的表达式,而exp1和 exp2可以为任何合法的Aviator表达式,并且不要求exp1和exp2返回的结果类型一致。 扩展特性 数字扩展 1、多个数字求和:sum对多个数字进行求和,忽略空值,作为0处理,提供兼容。 示例代码: /** * @description: 多个数字求和计算(其中任何一个数字为空则作为0处理) * @Date : 2021/4/11 9:43 AM * @Author : 石冬冬-Seig Heil */ public class SumTest { @Test public void test(){ Map evn = new HashMap(){{ put("x",2); put("y",4); put("z",8); }}; System.out.println(AviatorExecutor.executeBigDecimal(AviatorContext.builder().expression("sum(x,y,z,h)").env(evn).build())); } }输出: 14 2、多个数字获取最大值:max对多个数字获取最大值,忽略空值,作为0处理,提供兼容。 示例代码: /** * @description: 多个数字求最大值(其中任何一个数字为空则作为0处理) * @Date : 2021/4/11 9:43 AM * @Author : 石冬冬-Seig Heil */ public class MaxTest { @Test public void test(){ Map evn = new HashMap(){{ put("x",2); put("y",4); put("z",8); }}; System.out.println(AviatorExecutor.executeBigDecimal(AviatorContext.builder().expression("max(x,y,z,h)").env(evn).build())); } }输出: 8 3、多个数字获取最大值:min对多个数字获取最小值,忽略空值,作为0处理,提供兼容。 示例代码: /** * @description: 多个数字求最小值(其中任何一个数字为空则作为0处理) * @Date : 2021/4/11 9:43 AM * @Author : 石冬冬-Seig Heil */ public class MinTest { @Test public void test(){ Map evn = new HashMap(){{ put("x",2); put("y",4); put("z",8); }}; System.out.println(AviatorExecutor.executeBigDecimal(AviatorContext.builder().expression("min(x,y,z,h)").env(evn).build())); } }输出: 2 4、向上取整:ceil向上取整 示例代码: /** * @description: 向上取整 * @Date : 2021/4/11 9:43 AM * @Author : 石冬冬-Seig Heil */ public class CeilTest { @Test public void test(){ System.out.println(AviatorExecutor.executeBigDecimal(AviatorContext.builder().expression("ceil(1.2)").env(Collections.emptyMap()).build())); System.out.println(AviatorExecutor.executeBigDecimal(AviatorContext.builder().expression("ceil(1.6)").env(Collections.emptyMap()).build())); System.out.println(AviatorExecutor.executeBigDecimal(AviatorContext.builder().expression("ceil(201)").env(Collections.emptyMap()).build())); System.out.println(AviatorExecutor.executeBigDecimal(AviatorContext.builder().expression("ceil(196)").env(Collections.emptyMap()).build())); } }输出: 2.0 2.0 201.0 196.0 5、向下取整:floor向上取整 示例代码: /** * @description: 向下取整 * @Date : 2021/4/11 9:43 AM * @Author : 石冬冬-Seig Heil */ public class FloorTest { @Test public void test(){ System.out.println(AviatorExecutor.executeBigDecimal(AviatorContext.builder().expression("floor(1.2)").env(Collections.emptyMap()).build())); System.out.println(AviatorExecutor.executeBigDecimal(AviatorContext.builder().expression("floor(1.6)").env(Collections.emptyMap()).build())); System.out.println(AviatorExecutor.executeBigDecimal(AviatorContext.builder().expression("floor(201)").env(Collections.emptyMap()).build())); System.out.println(AviatorExecutor.executeBigDecimal(AviatorContext.builder().expression("floor(196)").env(Collections.emptyMap()).build())); } }输出: 1.0 1.0 201.0 196.0 6、四舍五入:round四舍五入 示例代码: /** * @description: 四舍五入 * @Date : 2021/4/11 9:43 AM * @Author : 石冬冬-Seig Heil */ public class RoundTest { @Test public void test(){ System.out.println(AviatorExecutor.executeBigDecimal(AviatorContext.builder().expression("round(1.2)").env(Collections.emptyMap()).build())); System.out.println(AviatorExecutor.executeBigDecimal(AviatorContext.builder().expression("round(1.6)").env(Collections.emptyMap()).build())); System.out.println(AviatorExecutor.executeBigDecimal(AviatorContext.builder().expression("round(201)").env(Collections.emptyMap()).build())); System.out.println(AviatorExecutor.executeBigDecimal(AviatorContext.builder().expression("round(196)").env(Collections.emptyMap()).build())); } }输出: 1 2 201 196 7、精度处理:scale精度处理,具体参数说明查看 org.suze.aviator.function.number.Scale 示例代码: /** * @description: 对数字取整方式 和 精度进位 处理 * @Date : 2021/4/11 9:43 AM * @Author : 石冬冬-Seig Heil */ public class ScaleTest { @Test public void test(){ Map evn = new HashMap(){{ put("x",15.344); }}; System.out.println(AviatorExecutor.executeBigDecimal(AviatorContext.builder().expression("scale(x,0,0)").env(evn).build())); System.out.println(AviatorExecutor.executeBigDecimal(AviatorContext.builder().expression("scale(x,0,1)").env(evn).build())); System.out.println(AviatorExecutor.executeBigDecimal(AviatorContext.builder().expression("scale(x,0,2)").env(evn).build())); System.out.println(AviatorExecutor.executeBigDecimal(AviatorContext.builder().expression("scale(x,-2,1)").env(evn).build())); System.out.println(AviatorExecutor.executeBigDecimal(AviatorContext.builder().expression("scale(x,-2,2)").env(evn).build())); } }输出: 15 16 15 100 0 集合扩展 1、判断一个字符串是否在一个字符串区间集合中:in(finder,delimiter,values)判断一个字符串是否在一个字符串区间集合中,finder代表查找项,delimiter字符串分隔符,values以delimiter分割的字符串。 示例代码: /** * @description: 判断一个字符串是否在一个字符串区间集合中 * @Date : 2021/4/11 9:43 AM * @Author : 石冬冬-Seig Heil */ public class InTest { @Test public void test(){ Map evn = new HashMap(){{ put("x",15); }}; String expression = "in(x, ',' , '15,34,22')"; AviatorContext ctx = AviatorContext.builder().expression(expression).env(evn).build(); System.out.println(AviatorExecutor.executeBoolean(ctx)); } }输出: true 2、判断一个字符串是否不在一个字符串区间集合中:notin(finder,delimiter,values)判断一个字符串是否不在一个字符串区间集合中,finder代表查找项,delimiter字符串分隔符,values以delimiter分割的字符串。 示例代码: /** * @description: 判断一个字符串是否在一个字符串区间集合中 * @Date : 2021/4/11 9:43 AM * @Author : 石冬冬-Seig Heil */ public class InTest { @Test public void test(){ Map evn = new HashMap(){{ put("x",15); }}; String expression = "notin(x, ',' , '15,34,22')"; AviatorContext ctx = AviatorContext.builder().expression(expression).env(evn).build(); System.out.println(AviatorExecutor.executeBoolean(ctx)); } }输出: false 通用函数基于日常业务场景需求,扩展的相关自定义函数。 1、两日期相差天数,参数类型为date:days.diff(current,destination)两日期相差天数,参数类型为date 示例代码: /** * @description: 两日期相差天数,参数类型为date * @Date : 2021/4/11 10:19 AM * @Author : 石冬冬-Seig Heil */ public class DiffDaysTest { @SneakyThrows @Test public void test(){ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); Map evn = new HashMap(){{ put("current",simpleDateFormat.parse("2021-04-11")); put("destination",simpleDateFormat.parse("2020-04-11")); }}; String expression = "days.diff(current,destination)"; AviatorContext ctx = AviatorContext.builder().expression(expression).env(evn).build(); System.out.println( AviatorExecutor.executeBigDecimal(ctx)); } }输出: 365 2、获取生日年龄:age(date)根据出生年月日计算年龄,出生年月日类型为字符串 示例代码: /** * @description: 根据出生年月日计算年龄,出生年月日类型为字符串 * @Date : 2021/4/11 10:19 AM * @Author : 石冬冬-Seig Heil */ public class AgeTest { @SneakyThrows @Test public void test(){ Map evn = new HashMap(){{ put("birth","19880808"); }}; String expression = "age(birth)"; AviatorContext ctx = AviatorContext.builder().expression(expression).env(evn).build(); System.out.println("age:" + AviatorExecutor.execute(ctx)); } }输出: 32 3、截取字符串中的数字求和:string.numbers.sum截取字符串中的数字求和 示例代码: /** * @description: 截取字符串中的数字求和 * @Date : 2021/4/11 10:19 AM * @Author : 石冬冬-Seig Heil */ public class StringNumbersSumTest { @SneakyThrows @Test public void test(){ String str = "保费借款金额:人民币(第一年:5600.00元;第二年:1110.00元;第三年:1000.00元)"; Map evn = new HashMap(){{ put("str",str); }}; String expression = "string.numbers.sum(str, '-', ':', '元')"; AviatorContext ctx = AviatorContext.builder().expression(expression).env(evn).cached(false).build(); System.out.println(AviatorExecutor.execute(ctx)); } }输出: 7710.00 4、数字转大写金额:chinese.number.upper(num)截取字符串中的数字求和 示例代码: /** * @description: 数字转大写金额 * @Date : 2021/4/11 10:19 AM * @Author : 石冬冬-Seig Heil */ public class ChineseNumberUpperTest { @SneakyThrows @Test public void test(){ BigDecimal num = new BigDecimal("11111.01"); Map evn = new HashMap(){{ put("num",num); }}; String expression = "chinese.number.upper(num)"; AviatorContext ctx = AviatorContext.builder().expression(expression).env(evn).build(); System.out.println(AviatorExecutor.execute(ctx)); } }输出: 壹万壹仟壹佰壹拾壹元零壹分 对象函数为空时,设置一个默认值 1、为空时,设置一个默认值:nvl(value,defaultValue)两日期相差天数,参数类型为date 示例代码: /** * @description: 根据出生年月日计算年龄,出生年月日类型为字符串 * @Date : 2021/4/11 10:19 AM * @Author : 石冬冬-Seig Heil */ public class NvlTest { @SneakyThrows @Test public void test(){ String expression = "nvl(a,0)"; AviatorContext ctx = AviatorContext.builder().expression(expression).env(Collections.emptyMap()).build(); System.out.println(AviatorExecutor.executeBigDecimal(ctx)); } }输出: 0 2、字符串转数字:objects.toNumber(value,defaultValue)字符串转数字,如果字符串为空,则使用默认值作为返回值,objects.toNumber(value,defaultValue) 示例代码: /** * @description: objects.toNumber(x,y) * @Date : 2021/4/11 10:19 AM * @Author : 石冬冬-Seig Heil */ public class ToNumberTest { @SneakyThrows @Test public void test(){ String expression = "objects.toNumber('1',0)"; AviatorContext ctx = AviatorContext.builder().expression(expression).env(Collections.emptyMap()).build(); System.out.println(AviatorExecutor.executeBigDecimal(ctx)); } }输出: 1 3、数字转字符串:objects.toString(value,defaultValue)数字转字符串,如果数字为空,则使用默认值作为返回值,objects.toString(value,defaultValue) 示例代码: /** * @description: 数字转字符串,如果数字为空,则使用默认值作为返回值,objects.toString(value,defaultValue) * @Date : 2021/4/11 10:19 AM * @Author : 石冬冬-Seig Heil */ public class ToStringTest { @SneakyThrows @Test public void test(){ String expression = "objects.toString(1,'0')"; AviatorContext ctx = AviatorContext.builder().expression(expression).env(Collections.emptyMap()).build(); System.out.println(AviatorExecutor.executeBigDecimal(ctx)); } }输出: 1 高级特性示例代码: /** * @description: 基于Aviator测试类 * @Date : 2018/9/7 下午6:00 * @Author : 石冬冬-Seig Heil([email protected]) */ @Slf4j public class AviatorObjectTest { @Test public void object_instance(){ Teacher teacher = new Teacher(){{ setName("im"); setScore(20); }}; Student student = new Student(){{ setName("Jack"); setScore(22); }}; Map env = new HashMap(){{ put("teacher",teacher); put("student",student); }}; Object value = AviatorExecutor.execute(AviatorContext.builder().env(env).expression("student.name").build()); System.out.println(value); } @Data @NoArgsConstructor @AllArgsConstructor public class Colleague { private String name; private double score; } @Data @NoArgsConstructor public class Student extends Colleague { public Student(String name, double score) { super(name, score); } } @Data @NoArgsConstructor public class Teacher extends Colleague { } }输出: Jack 扩展阅读CSDN 介绍 掘金 介绍 Aviator 源码地址 Aviator api 相关文档 |
CopyRight 2018-2019 实验室设备网 版权所有 |