Hello, everyone. I'm your good friend - Xiaofeng^
Introduction to Aviator
Aviator is a high-performance and lightweight expression evaluation engine implemented in java language, which is mainly used for dynamic evaluation of various expressions. Now there are many open source java expression evaluation engines available. Why do you need Aviator?
The implementation idea of aviator is very different from other lightweight evaluators. Other evaluators generally run by interpretation, while Aviator directly compiles expressions into Java bytecode and gives them to the JVM for execution. In short, aviator is positioned between a heavyweight scripting language such as Groovy and a lightweight expression engine such as ikeexpression.
Aviator feature
- Most operators are supported, including arithmetic operator, relational operator, logical operator, bit operator, regular matching operator (= ~), ternary expression?:, It also supports the priority of operators and the mandatory priority of parentheses. For details, see the list of operators later.
- Support function calls and custom functions
- Support regular expression matching, which is similar to the matching syntax of ruby and Perl, and support Ruby like $digit to point to matching groups.
- Automatic type conversion: when an operation is performed, the operand type will be automatically determined and converted accordingly. If it cannot be converted, an exception will be thrown.
- It supports incoming variables and nested variable access similar to a.b.c.
- Lightweight, high performance
Maven dependency
<dependency> <groupId>com.googlecode.aviator</groupId> <artifactId>aviator</artifactId> <version>5.2.3</version> </dependency>
Starting from version 3.2.0, Aviator only supports JDK 7 and above. JDK 6 please use the stable version of 3.1.1.
Usage scenario of Aviator
Execute expression
Aviator is used centrally through COM googlecode. aviator. Aviatorevaluator is handled by this entry class.
- Aviator supports common arithmetic operators, including + - * /% five binary operators and unary operator - (negative).
- Where - * /% and unary - can only act on Number type.
- +It can be used not only for Number type, but also for the addition of String or the addition of String and other objects.
- Aviator specifies that any type is added to String and the result is String.
- The numeric type of Aviator only supports Long and Double. Any integer will be converted to Long and any floating-point number will be converted to Double, including the variable value passed in by the user.
import com.googlecode.aviator.AviatorEvaluator; /** * @author Xiaofeng * @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); } }
Operation result:
6
Compile expression
The examples mentioned above are all expressions executed directly. In fact, Aviator has done the compilation and execution work for you. You can compile the expression yourself, return a compiled result, and then pass in different env s to reuse the compiled results and improve the performance. This is the more recommended way to use
import com.googlecode.aviator.AviatorEvaluator; import java.util.HashMap; import java.util.Map; /** * @author Xiaofeng * @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); } }
Operation result:
10.1 xiaoxiaofeng
Call function
Aviator supports function calls. The style of function calls is similar to lua
import com.googlecode.aviator.AviatorEvaluator; /** * @author Xiaofeng * @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))")); } }
Operation result:
12 xiao true true
Accessing arrays and collections
You can access arrays and Java. Net files through brackets util. List object, you can use map Key to access Java util. value corresponding to key in map
import com.googlecode.aviator.AviatorEvaluator; import java.util.*; /** * @author Xiaofeng * @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)); } }
Operation result:
xiao feng;array[0]+array[1]+array[2]=6;today is Fri Feb 25 15:24:10 CST 2022
ternary operator
Aviator does not provide if else statement, but provides ternary operator?:, bool? exp1: exp2. bool must be an expression of Boolean type, while Exp1 and exp2 can be any legal Aviator expression, and the result types returned by Exp1 and exp2 are not required to be the same.
import com.googlecode.aviator.AviatorEvaluator; /** * @author Xiaofeng * @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); } }
Operation result:
yes
Logical and relational operators
The logical operators supported by Aviator include the unary negative operator!, And logical and &, logical or. The operand of a logical operator can only be Boolean.
The relational operators supported by Aviator include <, < =, >, > =, = =,! =.
Relational operators can be used to compare the relationship between numbers, strings, patterns, Boolean, variables and other types and nil. Different types cannot be compared with each other except nil.
import com.googlecode.aviator.AviatorEvaluator; /** * @author Xiaofeng * @date 2022/2/24 */ public class AviatorEvaluatorUtil { public static void main(String[] args) { System.out.println(AviatorEvaluator.execute("(1>0||0<1)&&1!=0")); } }
Operation result:
true
Bitwise Operators
Aviator supports all Java bitwise operators, including &, |, ^, ~, > >, <, > >.
import com.googlecode.aviator.AviatorEvaluator; /** * @author Xiaofeng * @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")); } }
Operation result:
40 25
Operator list
Aviator supports the priority of operators and allows you to force the priority through parentheses. The following is a complete list of operators, in order of priority from high to low
Serial number | Operator | Associativity | Operand limit |
---|---|---|---|
0 | () [ ] | From left to right | () for function calls, [] for arrays and Java util. The element access of list requires that the index in [indx] must be an integer |
1 | ! - | Right to left | ! Can be used for Boolean, - can only be used for Number |
2 | * / % | From left to right | Between Number |
3 | + - | From left to right | +- can be used between numbers, + can also be used between strings, or between strings and other objects |
4 | < <= > >= | From left to right | Between Number, String, Pattern, variable, other types and nil |
5 | == != =~ | From left to right | ==And= It works between numbers, strings, patterns, variables, other types and nil, and between String and Java util. Between date, = ~ can only work between String and Pattern |
6 | && | From left to right | Short circuit between Boolean |
7 | || | From left to right | Short circuit between Boolean |
8 | ? : | Right to left | The result of the first operand must be Boolean, and the results of the second and third operands are unlimited |
Built in function
Function name | explain |
---|---|
sysdate() | Returns the current date object Java util. Date |
rand() | Returns a random number between 0 and 1, of type double |
print([out],obj) | Print the object. If out is specified, print to out, otherwise output to the console |
println([out],obj) | Similar to print, but wrap after output |
now() | Return to system currentTimeMillis |
long(v) | Change the type of the value to long |
double(v) | Change the value type to double |
str(v) | Change the type of the value to string |
date_to_string(date,format) | Convert the Date object into a string in a specific format. New in 2.1.1 |
string_to_date(source,format) | Convert a string in a specific format into a Date object, new in 2.1.1 |
string.contains(s1,s2) | Judge whether s1 contains s2 and return Boolean |
string.length(s) | Find the length of the string and return Long |
string.startsWith(s1,s2) | Whether s1 starts with s2 and returns Boolean |
string.endsWith(s1,s2) | Whether s1 ends with s2 and returns Boolean |
string.substring(s,begin[,end]) | Intercept the string s from begin to end. If end is ignored, it will be from begin to end, which is the same as Java util. String. Substring. |
string.indexOf(s1,s2) | s1.0 in java Indexof (s2), find the starting index position of s2 in s1. If it does not exist, it is - 1 |
string.split(target,regex,[limit]) | String in Java The split method is the same, and a new function is added in 2.1.1 |
string.join(seq,seperator) | Connect the elements in the set seq with seperator s as intervals to form a string. 2.1.1 adds a new function |
string.replace_first(s,regex,replacement) | String in Java Replacefirst method, added in 2.1.1 |
string.replace_all(s,regex,replacement) | String in Java Replaceall method, 2.1.1 NEW |
math.abs(d) | Find the absolute value of d |
math.sqrt(d) | Find the square root of d |
math.pow(d1,d2) | Find the power d2 of d1 |
math.log(d) | Find the natural logarithm of d |
math.log10(d) | Find the logarithm of d Based on 10 |
math.sin(d) | Sine function |
math.cos(d) | cosine function |
math.tan(d) | Tangent function |
map(seq,fun) | Apply the function fun to each element of the set seq and return the set composed of new elements |
filter(seq,predicate) | Act the predicate on each element of the set and return the set composed of elements with the predicate true |
count(seq) | Returns the collection size |
include(seq,element) | Judge whether the element is in the set seq and return the boolean value |
sort(seq) | Sort collection, which is only valid for arrays and lists, and returns a new collection after sorting |
reduce(seq,fun,init) | fun receives two parameters. The first is the set element and the second is the cumulative function. This function is used to act on each element and initial value of the set and return the final init value |
seq.eq(value) | Returns a predicate used to determine whether the passed in parameter is equal to value. It is used for filter functions, such as filter(seq,seq.eq(3)). Filter returns a set of elements equal to 3 |
seq.neq(value) | And SEQ Similar to EQ, it returns the predicate that determines that it is not equal to |
seq.gt(value) | Returns a predicate that determines whether it is greater than value |
seq.ge(value) | Returns a predicate that determines whether it is greater than or equal to value |
seq.lt(value) | Returns the predicate that determines whether it is less than value |
seq.le(value) | Returns the predicate that determines whether it is less than or equal to value |
seq.nil() | Returns the predicate that determines whether it is nil |
seq.exists() | Returns a predicate judged not to be nil |
About me
I am Xiaofeng who only has great dreams and is extraordinary. I like writing and making friends
Let's hurry and grab me. Click on the bottom of my WeChat official account. 2022, we will progress together ~ ~