其他分享
首页 > 其他分享> > 去掉复杂的逻辑计算,get一下Aviator吧

去掉复杂的逻辑计算,get一下Aviator吧

作者:互联网

哈喽,大家好,我是你们的好朋友——笑小枫 ^ _ ^

笑小枫的专属目录

Aviator简介

Aviator是一个高性能、轻量级的java语言实现的表达式求值引擎,主要用于各种表达式的动态求值。现在已经有很多开源可用的java表达式求值引擎,为什么还需要Aviator呢?

Aviator的实现思路与其他轻量级的求值器很不相同,其他求值器一般都是通过解释的方式运行,而Aviator则是直接将表达式编译成Java字节码,交给JVM去执行。简单来说,Aviator的定位是介于Groovy这样的重量级脚本语言和IKExpression这样的轻量级表达式引擎之间。

Aviator特性

Maven依赖

<dependency>
      <groupId>com.googlecode.aviator</groupId>
      <artifactId>aviator</artifactId>
      <version>5.2.3</version>
 </dependency>

从 3.2.0 版本开始, Aviator 仅支持 JDK 7 及其以上版本。 JDK 6 请使用 3.1.1 这个稳定版本。

Aviator的使用场景

执行表达式

Aviator的使用都是集中通过com.googlecode.aviator.AviatorEvaluator这个入口类来处理。

import com.googlecode.aviator.AviatorEvaluator;

/**
 * @author 笑小枫
 * @date 2022/2/24
 */
public class AviatorEvaluatorUtil {

    public static void main(String[] args) {
        Long result = (Long) AviatorEvaluator.execute("1+2+3");
        System.out.println(result);
    }
}

运算结果:

6

编译表达式

上面提到的例子都是直接执行表达式,事实上Aviator背后都帮你做了编译并执行的工作。你可以自己先编译表达式,返回一个编译的结果,然后传入不同的env来复用编译结果,提高性能,这是更推荐的使用方式

import com.googlecode.aviator.AviatorEvaluator;

import java.util.HashMap;
import java.util.Map;

/**
 * @author 笑小枫
 * @date 2022/2/24
 */
public class AviatorEvaluatorUtil {

    public static void main(String[] args) {
        Map<String, Object> env2 = new HashMap<>(16);
        env2.put("a2", 10.1);
        env2.put("b2", 0.1);
        env2.put("c2", 0.1);
        String expression2 = "a2+b2-c2";
        Double result2 = (Double) AviatorEvaluator.execute(expression2, env2, true);
        System.out.println(result2);

        Map<String, Object> env3 = new HashMap<>(16);
        env3.put("a3", "xiao");
        env3.put("b3", "xiao");
        env3.put("c3", "feng");
        String expression3 = "a3+b3+c3";
        String result3 = AviatorEvaluator.execute(expression3, env3, true).toString();
        System.out.println(result3);
    }
}

运算结果:

10.1
xiaoxiaofeng

调用函数

Aviator支持函数调用,函数调用的风格类似lua

import com.googlecode.aviator.AviatorEvaluator;

/**
 * @author 笑小枫
 * @date 2022/2/24
 */
public class AviatorEvaluatorUtil {

    public static void main(String[] args) {
        System.out.println(AviatorEvaluator.execute("string.length('xiaoxiaofeng')"));
        System.out.println(AviatorEvaluator.execute("string.substring('xiaoxiaofeng',0,4)"));
        System.out.println(AviatorEvaluator.execute("string.contains(\"xiaoxiaofeng\",\"feng\")"));
        System.out.println(AviatorEvaluator.execute("string.contains(\"xiaoxiaofeng\",string.substring('xiaoxiaofeng',1,3))"));
    }
}

运算结果:

12
xiao
true
true

访问数组和集合

可以通过中括号去访问数组和java.util.List对象,可以通过map.key访问java.util.Mapkey对应的value

import com.googlecode.aviator.AviatorEvaluator;

import java.util.*;


/**
 * @author 笑小枫
 * @date 2022/2/24
 */
public class AviatorEvaluatorUtil {

    public static void main(String[] args) {

        List<String> list = new ArrayList<>();
        list.add("xiao");
        list.add(" feng");

        int[] array = new int[3];
        array[0] = 1;
        array[1] = 2;
        array[2] = 3;

        final Map<String, Date> map = new HashMap<>();
        map.put("date", new Date());

        Map<String, Object> env = new HashMap<>();
        env.put("list", list);
        env.put("array", array);
        env.put("dateMap", map);

        System.out.println(AviatorEvaluator.execute(
                "list[0]+list[1]+';array[0]+array[1]+array[2]='+(array[0]+array[1]+array[2]) +';today is '+dateMap.date ", env));
    }
}

运算结果:

xiao feng;array[0]+array[1]+array[2]=6;today is Fri Feb 25 15:24:10 CST 2022

三元操作符

Aviator 没有提供if else语句,但是提供了三元运算符?:,形式为bool ? exp1: exp2。 其中bool必须为Boolean类型的表达式, 而exp1和exp2可以为任何合法的Aviator表达式,并且不要求exp1和exp2返回的结果类型一致。

import com.googlecode.aviator.AviatorEvaluator;

/**
 * @author 笑小枫
 * @date 2022/2/24
 */
public class AviatorEvaluatorUtil {

    public static void main(String[] args) {
        Map<String, Object> env4 = new HashMap<>();
        env4.put("a", 1);
        String result = (String) AviatorEvaluator.execute("a>0? 'yes':'no'", env4);
        System.out.println(result);

    }
}

运算结果:

yes

逻辑运算符和关系运算符

Aviator的支持的逻辑运算符包括,一元否定运算符!,以及逻辑与的&&,逻辑或的||。逻辑运算符的操作数只能为Boolean。

Aviator支持的关系运算符包括<, <=, >, >=, ==, !=

关系运算符可以作用于Number之间、String之间、Pattern之间、Boolean之间、变量之间以及其他类型与nil之间的关系比较, 不同类型除了nil之外不能相互比较。

import com.googlecode.aviator.AviatorEvaluator;


/**
 * @author 笑小枫
 * @date 2022/2/24
 */
public class AviatorEvaluatorUtil {

    public static void main(String[] args) {
        System.out.println(AviatorEvaluator.execute("(1>0||0<1)&&1!=0"));
    }
}

运算结果:

true

位运算符

Aviator 支持所有的 Java 位运算符,包括&, |, ^, ~, >>, <<, >>>

import com.googlecode.aviator.AviatorEvaluator;

/**
 * @author 笑小枫
 * @date 2022/2/24
 */
public class AviatorEvaluatorUtil {

    public static void main(String[] args) {
        System.out.println(AviatorEvaluator.execute("10<<2"));
        System.out.println(AviatorEvaluator.execute("100>>>2"));

    }
}

运算结果:

40
25

操作符列表

Aviator支持操作符的优先级,并且允许通过括号来强制优先级,下面是完整的操作符列表,按照优先级从高到低的顺序排列

序号操作符结合性操作数限制
0() [ ]从左到右()用于函数调用,[ ]用于数组和java.util.List的元素访问,要求[indx]中的index必须为整型
1! -从右到左! 能用于Boolean,- 仅能用于Number
2* / %从左到右Number之间
3+ -从左到右+ - 都能用于Number之间, + 还能用于String之间,或者String和其他对象
4< <= > >=从左到右Number之间、String之间、Pattern之间、变量之间、其他类型与nil之间
5== != =~从左到右==和!=作用于Number之间、String之间、Pattern之间、变量之间、其他类型与nil之间以及String和java.util.Date之间,=~仅能作用于String和Pattern之间
6&&从左到右Boolean之间,短路
7||从左到右Boolean之间,短路
8? :从右到左第一个操作数的结果必须为Boolean,第二和第三操作数结果无限制

内置函数

函数名称说明
sysdate()返回当前日期对象 java.util.Date
rand()返回一个介于 0-1 的随机数,double 类型
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.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 的谓词

关于我

我就是那只有伟大梦想,又特平凡,喜欢写作,爱交友的笑小枫

大家快点来抓住我吧,点击下方关注我的微信公众号呦,2022,我们一起进步~~~

标签:String,seq,get,AviatorEvaluator,运算符,去掉,Aviator,out
来源: https://blog.csdn.net/qq_34988304/article/details/123136746