Aviator计算引擎 您所在的位置:网站首页 java自定义运算符 Aviator计算引擎

Aviator计算引擎

#Aviator计算引擎| 来源: 网络整理| 查看: 265

[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 实验室设备网 版权所有