Aviator表达式求值引擎
Posted ESOO
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Aviator表达式求值引擎相关的知识,希望对你有一定的参考价值。
Aviator是一个轻量级、高性能的Java表达式执行引擎,它动态地将表达式编译成字节码并运行。
特性包括:
- 支持绝大多数运算操作符,包括算术操作符、关系运算符、逻辑操作符、位运算符、正则匹配操作符(=~)、三元表达式(?:)
- 支持操作符优先级和括号强制设定优先级
- 逻辑运算符支持短路运算。
- 支持丰富类型,例如nil、整数和浮点数、字符串、正则表达式、日期、变量等,支持自动类型转换。
- 内置一套强大的常用函数库
- 可自定义函数,易于扩展
- 可重载操作符
- 支持大数运算(BigInteger)和高精度运算(BigDecimal)
- 性能优秀
下面来正式使用:
先引入依赖
<dependency> <groupId>com.googlecode.aviator</groupId> <artifactId>aviator</artifactId> <version>3.3.0</version> </dependency>
写个简单的用法,先来了解这个表达式:
package com.xzg.aviator; import com.googlecode.aviator.AviatorEvaluator; import java.util.HashMap; import java.util.Map; /** * Created by Administrator on 2018/5/22. * * @author XieZG * @date 2018/5/22 */ public class TestCalc public static void main(String[] args) int[] a = new int[]6, 7, 8, 9; Map<String, Object> env = new HashMap<String, Object>(); env.put("a", a); System.out.println(AviatorEvaluator.execute("1 + 2 + 3")); System.out.println(AviatorEvaluator.execute("a[1] + 100", env)); System.out.println(AviatorEvaluator.execute("'a[1]=' + a[1]", env)); //求数组长度 System.out.println(AviatorEvaluator.execute("count(a)", env)); //求数组总和 System.out.println(AviatorEvaluator.execute("reduce(a, +, 0)", env)); //检测数组每个元素都在 0 <= e < 10 之间。 System.out.println(AviatorEvaluator.execute("seq.every(a, seq.and(seq.ge(0), seq.lt(10)))", env));
可以看到aviator支持运算,取值,还有一个内置函数可以用。有些童鞋可能不太了解,说这些直接写java程序也能做,为啥要用表达式。其实是有些场景需要使用它,比如风控系统,是要给业务配置表达式的,然后程序执行它,总不可能每次业务规则变更都要程序员来改吧。
而且aviator里还有reduce,sort等高阶函数,可以简化开发哦。
上面代码频繁使用了一个类com.googlecode.aviator.AviatorEvaluator,这个就是aviator表达式的入口类,所有表达式的使用都是通过这个类的。
然后再来个进阶的用法:
package com.xzg.aviator; import com.googlecode.aviator.AviatorEvaluator; import lombok.Data; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Map; /** * Created by Administrator on 2018/5/22. * * @author XieZG * @date 2018/5/22 */ public class TestAviator private String aa="jack"; public String getAa() return aa; public void setAa(String aa) this.aa = aa; public static void main(String[] args) Map<String, Object> env = new HashMap<String, Object>(); ArrayList<Integer> list = new ArrayList<Integer>(); list.add(3); list.add(20); list.add(10); env.put("list", list); env.put("email", "killme2008@gmail.com"); env.put("test", new TestAviator()); env.put("date",new Date()); String username = (String) AviatorEvaluator.execute("email=~/([\\\\w0-8]+)@\\\\w+[\\\\.\\\\w+]+/ ? $1 : 'unknow' ", env); System.out.println(username); System.out.println(AviatorEvaluator.exec("a>0? 'yes':'no'", 1)); System.out.println(AviatorEvaluator.execute("'test.aa ='+test.aa", env)); System.out.println(AviatorEvaluator.execute(" obj==nil", env)); System.out.println(AviatorEvaluator.execute(" date > '2018-05-21 00:00:00:00'", env)); System.out.println(AviatorEvaluator.execute(" date > '2018-05-22 12:00:00:00'", env)); Object result = AviatorEvaluator.execute("count(list)", env); System.out.println(result); // 3 result = AviatorEvaluator.execute("reduce(list,+,0)", env); System.out.println(result); // 33 result = AviatorEvaluator.execute("filter(list,seq.gt(9))", env); System.out.println(result); // [10, 20] result = AviatorEvaluator.execute("include(list,10)", env); System.out.println(result); // true result = AviatorEvaluator.execute("sort(list)", env); System.out.println(result); // [3, 10, 20] AviatorEvaluator.execute("map(list,println)", env);
简单说下,里面有正则,三元,null判断,对象属性获取,还有一些集合函数。
其实aviator支持的函数还挺多的:
内置函数
函数名称 | 说明 |
---|---|
sysdate() | 返回当前日期对象 java.util.Date |
rand() | 返回一个介于 0-1 的随机数,double 类型 |
rand(n) | 返回一个介于 0- n 的随机数,long 类型 |
print([out],obj) | 打印对象,如果指定 out,向 out 打印, 否则输出到控制台 |
println([out],obj) | 与 print 类似,但是在输出后换行 |
now() | 返回 System.currentTimeMillis |
long(v) | 将值的类型转为 long |
double(v) | 将值的类型转为 double |
str(v) | 将值的类型转为 string |
date_to_string(date,format) | 将 Date 对象转化化特定格式的字符串,2.1.1 新增 |
string_to_date(source,format) | 将特定格式的字符串转化为 Date 对 象,2.1.1 新增 |
string.contains(s1,s2) | 判断 s1 是否包含 s2,返回 Boolean |
string.length(s) | 求字符串长度,返回 Long |
string.startsWith(s1,s2) | s1 是否以 s2 开始,返回 Boolean |
string.endsWith(s1,s2) | s1 是否以 s2 结尾,返回 Boolean |
string.substring(s,begin[,end]) | 截取字符串 s,从 begin 到 end,如果忽略 end 的话,将从 begin 到结尾,与 java.util.String.substring 一样。 |
string.indexOf(s1,s2) | java 中的 s1.indexOf(s2),求 s2 在 s1 中 的起始索引位置,如果不存在为-1 |
string.split(target,regex,[limit]) | Java 里的 String.split 方法一致,2.1.1 新增函数 |
string.join(seq,seperator) | 将集合 seq 里的元素以 seperator 为间隔 连接起来形成字符串,2.1.1 新增函数 |
string.replace_first(s,regex,replacement) | Java 里的 String.replaceFirst 方法, 2.1.1 新增 |
string.replace_all(s,regex,replacement) | Java 里的 String.replaceAll 方法 , 2.1.1 新增 |
math.abs(d) | 求 d 的绝对值 |
math.sqrt(d) | 求 d 的平方根 |
math.pow(d1,d2) | 求 d1 的 d2 次方 |
math.log(d) | 求 d 的自然对数 |
math.log10(d) | 求 d 以 10 为底的对数 |
math.sin(d) | 正弦函数 |
math.cos(d) | 余弦函数 |
math.tan(d) | 正切函数 |
map(seq,fun) | 将函数 fun 作用到集合 seq 每个元素上, 返回新元素组成的集合 |
filter(seq,predicate) | 将谓词 predicate 作用在集合的每个元素 上,返回谓词为 true 的元素组成的集合 |
count(seq) | 返回集合大小 |
include(seq,element) | 判断 element 是否在集合 seq 中,返回 boolean 值 |
sort(seq) | 排序集合,仅对数组和 List 有效,返回排 序后的新集合 |
reduce(seq,fun,init) | fun 接收两个参数,第一个是集合元素, 第二个是累积的函数,本函数用于将 fun 作用在集合每个元素和初始值上面,返回 最终的 init 值 |
seq.every(seq, fun) | fun 接收集合的每个元素作为唯一参数,返回 true 或 false。当集合里的每个元素调用 fun 后都返回 true 的时候,整个调用结果为 true,否则为 false。 |
seq.not_any(seq, fun) | fun 接收集合的每个元素作为唯一参数,返回 true 或 false。当集合里的每个元素调用 fun 后都返回 false 的时候,整个调用结果为 true,否则为 false。 |
seq.some(seq, fun) | fun 接收集合的每个元素作为唯一参数,返回 true 或 false。当集合里的只要有一个元素调用 fun 后返回 true 的时候,整个调用结果立即为 true,否则为 false。 |
seq.eq(value) | 返回一个谓词,用来判断传入的参数是否跟 value 相等,用于 filter 函数,如filter(seq,seq.eq(3)) 过滤返回等于3 的元素组成的集合 |
seq.neq(value) | 与 seq.eq 类似,返回判断不等于的谓词 |
seq.gt(value) | 返回判断大于 value 的谓词 |
seq.ge(value) | 返回判断大于等于 value 的谓词 |
seq.lt(value) | 返回判断小于 value 的谓词 |
seq.le(value) | 返回判断小于等于 value 的谓词 |
seq.nil() | 返回判断是否为 nil 的谓词 |
seq.exists() | 返回判断不为 nil 的谓词 |
seq.and(p1, p2, p3, ...) | 组合多个谓词函数,返回一个新的谓词函数,当今仅当 p1、p2、p3 ...等所有函数都返回 true 的时候,新函数返回 true |
seq.or(p1, p2, p3, ...) | 组合多个谓词函数,返回一个新的谓词函数,当 p1, p2, p3... 其中一个返回 true 的时候,新函数立即返回 true,否则返回 false。 |
以上是关于Aviator表达式求值引擎的主要内容,如果未能解决你的问题,请参考以下文章