Aviator是一个轻量级、高性能的Java表达式执行引擎,它动态地将表达式编译成字节码并运行。
特性包括:
下面来正式使用:
先引入依赖
com.googlecode.aviator
aviator
3.3.0
写个简单的用法,先来了解这个表达式:
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 env = new HashMap();
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 env = new HashMap();
ArrayList list = new ArrayList();
list.add(3);
list.add(20);
list.add(10);
env.put("list", list);
env.put("email", "[email protected]");
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。 |