博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Fel轻量高效的表达式计算引擎
阅读量:3728 次
发布时间:2019-05-22

本文共 18516 字,大约阅读时间需要 61 分钟。

Fel是轻量级的高效的表达式计算引擎

更多干货

Fel在源自于企业项目,设计目标是为了满足不断变化的功能需求和性能需求。
Fel是开放的,引擎执行中的多个模块都可以扩展或替换。Fel的执行主要是通过函数实现,运算符(+、-等都是Fel函数),所有这些函数都是可以替换的,扩展函数也非常简单。
Fel有双引擎,同时支持解释执行和编译执行。可以根据性能要求选择执行方式。编译执行就是将表达式编译成字节码(生成java代码和编译模块都是可以扩展和替换的)

Fel有多快?

通常情况下,Fel-0.7每秒可以执行千万次表达式(不包含编译时间)。速度是Jexl-2.0的20倍以上。

目前还没有发现开源的表达式引擎比Fel快。

具体的数据请参见。

为何要使用Fel?

Fel语法和API非常简单,语法与基本相同,几乎没有学习成本。

Fel非常快,上面已经做了简单说明。

Fel整个包只有200多KB。

Fel可以非常方便的访问数组、集合、Map的元素和对象的属性。

Fel可以非常方便的调用对象的方法和类方法(如果这些还不够,可以添加自定义函数)。

Fel支持大数值高精度计算

Fel有良好的安全管理功能

如果Fel不能满足你的要求,扩展和修改Fel很简单。

Fel不能做什么?

Fel只支持表达式,不支持脚本。

Fel适用场景:

Fel适合处理海量数据,Fel良好的扩展性可以更好的帮助用户处理数据。

Fel同样适用于其他需要使用表达式引擎的地方(如果工作流、公式计算、数据有效性校验等等)

安装

1:获取Fel

项目主页: 下载地址:

Fel使用例子:

1:算术表达式:

[java]   
  1. FelEngine fel = new FelEngineImpl();      
  2. Object result = fel.eval("5000*12+7500");      
  3. System.out.println(result);     

输出结果:67500

2:变量

使用变量,其代码如下所示:

[java]   
  1. FelContext ctx = fel.getContext();      
  2. ctx.set("单价"5000);      
  3. ctx.set("数量"12);      
  4. ctx.set("运费"7500);      
  5. Object result = fel.eval("单价*数量+运费");      
  6. System.out.println(result);    

输出结果:67500

3:访问对象属性

在Fel中,可能非常方便的访问对象属性,示例代码如下所示

[java]   
  1. FelEngine fel = new FelEngineImpl();  
  2. FelContext ctx = fel.getContext();  
  3. Foo foo = new Foo();  
  4. ctx.set("foo", foo);  
  5. Map<String,String> m = new HashMap<String,String>();  
  6. m.put("ElName""fel");  
  7. ctx.set("m",m);  
  8.           
  9. //调用foo.getSize()方法。  
  10. Object result = fel.eval("foo.size");  
  11.   
  12. //调用foo.isSample()方法。  
  13. result = fel.eval("foo.sample");  
  14.                   
  15. //foo没有name、getName、isName方法  
  16. //foo.name会调用foo.get("name")方法。  
  17. result = fel.eval("foo.name");  
  18.                   
  19. //m.ElName会调用m.get("ElName");  
  20. result = fel.eval("m.ElName");  

4:访问数组、集合、Map

[java]   
  1. FelEngine fel = new FelEngineImpl();  
  2. FelContext ctx = fel.getContext();  
  3.   
  4. //数组  
  5. int[] intArray = {
    1,2,3};  
  6. ctx.set("intArray",intArray);  
  7. //获取intArray[0]  
  8. String exp = "intArray[0]";  
  9. System.out.println(exp+"->"+fel.eval(exp));  
  10.   
  11. //List  
  12. List<Integer> list = Arrays.asList(1,2,3);  
  13. ctx.set("list",list);  
  14. //获取list.get(0)  
  15. exp = "list[0]";  
  16. System.out.println(exp+"->"+fel.eval(exp));  
  17.   
  18. //集合  
  19. Collection<String> coll = Arrays.asList("a","b","c");  
  20. ctx.set("coll",coll);  
  21. //获取集合最前面的元素。执行结果为"a"  
  22. exp = "coll[0]";  
  23. System.out.println(exp+"->"+fel.eval(exp));  
  24.   
  25. //迭代器  
  26. Iterator<String> iterator = coll.iterator();  
  27. ctx.set("iterator", iterator);  
  28. //获取迭代器最前面的元素。执行结果为"a"  
  29. exp = "iterator[0]";  
  30. System.out.println(exp+"->"+fel.eval(exp));  
  31.   
  32. //Map  
  33. Map<String,String> m = new HashMap<String, String>();  
  34. m.put("name""HashMap");  
  35. ctx.set("map",m);  
  36. exp = "map.name";  
  37. System.out.println(exp+"->"+fel.eval(exp));  
  38.   
  39. //多维数组  
  40. int[][] intArrays= {
    {
    11,12},{
    21,22}};  
  41. ctx.set("intArrays",intArrays);  
  42. exp = "intArrays[0][0]";  
  43. System.out.println(exp+"->"+fel.eval(exp));  
  44.   
  45. //多维综合体,支持数组、集合的任意组合。  
  46. List<int[]> listArray = new ArrayList<int[]>();  
  47. listArray.add(new int[]{
    1,2,3});  
  48. listArray.add(new int[]{
    4,5,6});  
  49. ctx.set("listArray",listArray);  
  50. exp = "listArray[0][0]";  
  51. System.out.println(exp+"->"+fel.eval(exp));  

5:调用JAVA方法

[java]   
  1. FelEngine fel = new FelEngineImpl();     
  2. FelContext ctx = fel.getContext();     
  3. ctx.set("out", System.out);     
  4. fel.eval("out.println('Hello Everybody'.substring(6))");    

输出结果:Everybody

6:自定义上下文环境

[java]   
  1. //负责提供气象服务的上下文环境     
  2. FelContext ctx = new AbstractConetxt() {     
  3.     public Object get(Object name) {     
  4.         if("天气".equals(name)){     
  5.             return "晴";     
  6.         }     
  7.         if("温度".equals(name)){     
  8.             return 25;     
  9.         }     
  10.         return null;     
  11.     }     
  12. };     
  13. FelEngine fel = new FelEngineImpl(ctx);     
  14. Object eval = fel.eval("'天气:'+天气+';温度:'+温度");     
  15. System.out.println(eval);    

输出结果:天气:晴;温度:25

7:多层上下文环境(命名空间)

[java]   
  1. FelEngine fel = new FelEngineImpl();     
  2. String costStr = "成本";     
  3. String priceStr="价格";     
  4. FelContext baseCtx = fel.getContext();     
  5. //父级上下文中设置成本和价格     
  6. baseCtx.set(costStr, 50);     
  7. baseCtx.set(priceStr,100);     
  8.      
  9. String exp = priceStr+"-"+costStr;     
  10. Object baseCost = fel.eval(exp);     
  11. System.out.println("期望利润:" + baseCost);     
  12.      
  13. FelContext ctx = new ContextChain(baseCtx, new MapContext());     
  14. //通货膨胀导致成本增加(子级上下文 中设置成本,会覆盖父级上下文中的成本)     
  15. ctx.set(costStr,50+20 );     
  16. Object allCost = fel.eval(exp, ctx);     
  17. System.out.println("实际利润:" + allCost);    

输出结果:

期望利润:50

实际利润:30

8:编译执行

[java]   
  1. FelEngine fel = new FelEngineImpl();     
  2. FelContext ctx = fel.getContext();     
  3. ctx.set("单价"5000);     
  4. ctx.set("数量"12);     
  5. ctx.set("运费"7500);     
  6. Expression exp = fel.compile("单价*数量+运费",ctx);     
  7. Object result = exp.eval(ctx);     
  8. System.out.println(result);    

执行结果:67500

备注:适合处理海量数据,编译执行的速度基本与Java字节码执行速度一样快。

9:自定义函数

[java]   
  1. //定义hello函数     
  2. Function fun = new CommonFunction() {     
  3.   
  4.     public String getName() {     
  5.         return "hello";     
  6.     }     
  7.          
  8.     /*    
  9.      * 调用hello("xxx")时执行的代码   
  10.      */     
  11.     @Override     
  12.     public Object call(Object[] arguments) {     
  13.         Object msg = null;     
  14.         if(arguments!= null && arguments.length>0){     
  15.             msg = arguments[0];     
  16.         }     
  17.         return ObjectUtils.toString(msg);     
  18.     }     
  19.   
  20. };     
  21. FelEngine e = new FelEngineImpl();     
  22. //添加函数到引擎中。     
  23. e.addFun(fun);     
  24. String exp = "hello('fel')";     
  25. //解释执行     
  26. Object eval = e.eval(exp);     
  27. System.out.println("hello "+eval);     
  28. //编译执行     
  29. Expression compile = e.compile(exp, null);     
  30. eval = compile.eval(null);     
  31. System.out.println("hello "+eval);    

执行结果:

hello fel hello fel

10:调用静态方法

如果你觉得上面的自定义函数也麻烦,Fel提供的$函数可以方便的调用工具类的方法 熟悉的朋友肯定知道"$"函数的威力。Fel东施效颦,也实现了一个"$"函数,其作用是获取class和创建对象。结合点操作符,可以轻易的调用工具类或对象的方法。

[java]   
  1. //调用Math.min(1,2)  
  2. FelEngine.instance.eval("$('Math').min(1,2)");  
  3. //调用new Foo().toString();  
  4. FelEngine.instance.eval("$('com.greenpineyu.test.Foo.new').toString());  

通过"$('class').method"形式的语法,就可以调用任何等三方类包(commons lang等)及自定义工具类的方法,也可以创建对象,调用对象的方法。如果有需要,还可以直接注册Method到函数管理器中。

11 大数值计算(始于0.9版本)

Fel发布后,有些网友希望提供大数值计算功能,于是,大数值计算功能就有了。例子如下:

[java]   
  1. FelEngine fel = FelBuilder.bigNumberEngine();  
  2. String input = "111111111111111111111111111111+22222222222222222222222222222222";  
  3. Object value = fel.eval(input);  
  4. Object compileValue = fel.compile(input, fel.getContext()).eval(fel.getContext());  
  5. System.out.println("大数值计算(解释执行):" + value);  
  6. System.out.println("大数值计算(编译执行):" + compileValue);  

由上例子可以看出,大数值计算引擎和常规计算引擎在使用方法是相同的。如果表达式数值比较大,要求精度高,可使用大数值计算引擎。不足之处是效率没有常规计算引擎高。

安全(始于0.8版本)

为了防止出现“${'System'}.exit(1)”这样的表达式导致系统崩溃。Fel加入了安全管理器,主要是对方法访问进行控制。安全管理器中通过允许访问的方法列表(白名单)和禁止访问的方法列表(黑名单)来控制方法访问。将"java.lang.System. "加入到黑名单,表示System类的所有方法都不能访问。将"java.lang.Math. "加入白名单,表示只能访问Math类中的方法。如果你不喜欢这个安全管理器,可以自己开发一个,非常简单,只需要实现一个方法就可以了。

附基本Java工程源代码:

Example类:

[java]   
  1. public class Example {  
  2.   
  3.     public static void main(String[] args) {  
  4.   
  5.         System.out.println("-----------1.入门---------");  
  6.         helloworld();  
  7.   
  8.         System.out.println("-----------2.使用变量---------");  
  9.         useVariable();  
  10.   
  11.         System.out.println("-----------3.获取对象属性---------");  
  12.         getAttr();  
  13.   
  14.         System.out.println("---------4.调用对象的方法-----------");  
  15.         callMethod();  
  16.   
  17.         System.out.println("--------5.访问数组、集合------------");  
  18.         visitColl();  
  19.   
  20.         System.out.println("--------6.自定义上下文环境------------");  
  21.         context();  
  22.   
  23.         System.out.println("--------7.多层次上下文环境(变量命名空间)------------");  
  24.         contexts();  
  25.   
  26.         System.out.println("---------8.大数值计算-----------");  
  27.         testBigNumber();  
  28.   
  29.         System.out.println("----------9.函数----------");  
  30.         userFunction();  
  31.   
  32.         System.out.println("---------10.自定义 解释器-----------");  
  33.         userInterpreter();  
  34.   
  35.         System.out.println("----------11.操作符重载----------");  
  36.         operatorOverload();  
  37.   
  38.         System.out.println("----------12.速度测试----------");  
  39.         testSpeed();  
  40.   
  41.         System.out.println("----------13.静态方法----------");  
  42.         staticMethod();  
  43.     }  
  44.   
  45.     /** 
  46.      * 入门 
  47.      */  
  48.     public static void helloworld() {  
  49.         // FelEngine fel = new FelEngineImpl();  
  50.         Object result = FelEngine.instance.eval("5000*12+7500");  
  51.         System.out.println(result);  
  52.     }  
  53.   
  54.     /** 
  55.      * 使用变量 
  56.      */  
  57.     public static void useVariable() {  
  58.         FelEngine fel = getEngine();  
  59.         FelContext ctx = fel.getContext();  
  60.         ctx.set("单价"5000);  
  61.         ctx.set("数量"12);  
  62.         ctx.set("运费"7500);  
  63.         Object result = fel.eval("单价*数量+运费");  
  64.         System.out.println(result);  
  65.     }  
  66.   
  67.     /** 
  68.      * 获取对象属性 
  69.      */  
  70.     public static void getAttr() {  
  71.         FelEngine fel = getEngine();  
  72.         FelContext ctx = fel.getContext();  
  73.         Foo foo = new Foo();  
  74.         ctx.set("foo", foo);  
  75.         Map<String, String> m = new HashMap<String, String>();  
  76.         m.put("ElName""fel");  
  77.         ctx.set("m", m);  
  78.   
  79.         // 调用foo.getSize()方法。  
  80.         Object result = fel.eval("foo.size");  
  81.         System.out.println(result);  
  82.         // 调用foo.isSample()方法。  
  83.         result = fel.eval("foo.sample");  
  84.         System.out.println(result);  
  85.         // foo没有name、getName、isName方法  
  86.         // foo.name会调用foo.get("name")方法。  
  87.         result = fel.eval("foo.name");  
  88.         System.out.println(result);  
  89.         // m.ElName会调用m.get("ElName");  
  90.         result = fel.eval("m.ElName");  
  91.         System.out.println(result);  
  92.     }  
  93.   
  94.     /** 
  95.      * 调用对象的方法 
  96.      */  
  97.     public static void callMethod() {  
  98.         FelEngine fel = getEngine();  
  99.         FelContext ctx = fel.getContext();  
  100.         ctx.set("out", System.out);  
  101.         fel.eval("out.println('Hello Everybody'.substring(6))");  
  102.     }  
  103.   
  104.     /** 
  105.      * 访问数组、集合 
  106.      */  
  107.     public static void visitColl() {  
  108.         FelEngine fel = getEngine();  
  109.         FelContext ctx = fel.getContext();  
  110.   
  111.         // 数组  
  112.         int[] intArray = { 123 };  
  113.         ctx.set("intArray", intArray);  
  114.         // 获取intArray[0]  
  115.         String exp = "intArray[0]";  
  116.         System.out.println(exp + "->" + fel.eval(exp));  
  117.   
  118.         // List  
  119.         List<Integer> list = Arrays.asList(123);  
  120.         ctx.set("list", list);  
  121.         // 获取list.get(0)  
  122.         exp = "list[0]";  
  123.         System.out.println(exp + "->" + fel.eval(exp));  
  124.   
  125.         // 集合  
  126.         Collection<String> coll = Arrays.asList("a""b""c");  
  127.         ctx.set("coll", coll);  
  128.         // 获取集合最前面的元素。执行结果为"a"  
  129.         exp = "coll[0]";  
  130.         System.out.println(exp + "->" + fel.eval(exp));  
  131.   
  132.         // 迭代器  
  133.         Iterator<String> iterator = coll.iterator();  
  134.         ctx.set("iterator", iterator);  
  135.         // 获取迭代器最前面的元素。执行结果为"a"  
  136.         exp = "iterator[0]";  
  137.         System.out.println(exp + "->" + fel.eval(exp));  
  138.   
  139.         // Map  
  140.         Map<String, String> m = new HashMap<String, String>();  
  141.         m.put("name""Wangxiaoming");  
  142.         ctx.set("map", m);  
  143.         exp = "map.name";  
  144.         System.out.println(exp + "->" + fel.eval(exp));  
  145.   
  146.         // 多维数组  
  147.         int[][] intArrays = { { 1112 }, { 2122 } };  
  148.         ctx.set("intArrays", intArrays);  
  149.         exp = "intArrays[0][0]";  
  150.         System.out.println(exp + "->" + fel.eval(exp));  
  151.   
  152.         // 多维综合体,支持数组、集合的任意组合。  
  153.         List<int[]> listArray = new ArrayList<int[]>();  
  154.         listArray.add(new int[] { 123 });  
  155.         listArray.add(new int[] { 456 });  
  156.         ctx.set("listArray", listArray);  
  157.         exp = "listArray[0][0]";  
  158.         System.out.println(exp + "->" + fel.eval(exp));  
  159.     }  
  160.   
  161.     /** 
  162.      * 自定义上下文环境 
  163.      */  
  164.     public static void context() {  
  165.         // 负责提供气象服务的上下文环境  
  166.         FelContext ctx = new AbstractContext() {  
  167.             @Override  
  168.             public Object get(String name) {  
  169.                 if ("天气".equals(name)) {  
  170.                     return "晴";  
  171.                 }  
  172.                 if ("温度".equals(name)) {  
  173.                     return 25;  
  174.                 }  
  175.                 return null;  
  176.             }  
  177.   
  178.         };  
  179.         FelEngine fel = new FelEngineImpl(ctx);  
  180.         String exp = "'天气-----:'+天气+';温度------:'+温度";  
  181.         Object eval = fel.compile(exp, ctx).eval(ctx);  
  182.         System.out.println(eval);  
  183.     }  
  184.   
  185.     /** 
  186.      * 多层次上下文环境(变量命名空间) 
  187.      */  
  188.     public static void contexts() {  
  189.         FelEngine fel = getEngine();  
  190.         String costStr = "成本";  
  191.         String priceStr = "价格";  
  192.         FelContext baseCtx = fel.getContext();  
  193.         // 父级上下文中设置成本和价格  
  194.         baseCtx.set(costStr, 50);  
  195.         baseCtx.set(priceStr, 100);  
  196.   
  197.         String exp = priceStr + "-" + costStr;  
  198.         Object baseCost = fel.eval(exp);  
  199.         System.out.println("期望利润:" + baseCost);  
  200.   
  201.         FelContext ctx = new ContextChain(baseCtx, new MapContext());  
  202.         // 通货膨胀导致成本增加(子级上下文 中设置成本,会覆盖父级上下文中的成本)  
  203.         ctx.set(costStr, 50 + 20);  
  204.         Object allCost = fel.eval(exp, ctx);  
  205.         System.out.println("实际利润:" + allCost);  
  206.     }  
  207.   
  208.     /** 
  209.      * 大数值计算 
  210.      */  
  211.     public static void testBigNumber() {  
  212.         // 构建大数值计算引擎  
  213.         FelEngine fel = FelBuilder.bigNumberEngine();  
  214.         String input = "111111111111111111111111111111+22222222222222222222222222222222";  
  215.         Object value = fel.eval(input);// 解释执行  
  216.         Object compileValue = fel.compile(input, fel.getContext()).eval(  
  217.                 fel.getContext());// 编译执行  
  218.         System.out.println("大数值计算(解释执行):" + value);  
  219.         System.out.println("大数值计算(编译执行):" + compileValue);  
  220.     }  
  221.   
  222.     /** 
  223.      * 函数 
  224.      */  
  225.     public static void userFunction() {  
  226.         // 定义hello函数  
  227.         Function fun = new CommonFunction() {  
  228.   
  229.             @Override  
  230.             public String getName() {  
  231.                 return "hello";  
  232.             }  
  233.   
  234.             /* 
  235.              * 调用hello("xxx")时执行的代码 
  236.              */  
  237.             @Override  
  238.             public Object call(Object[] arguments) {  
  239.                 Object msg = null;  
  240.                 if (arguments != null && arguments.length > 0) {  
  241.                     msg = arguments[0];  
  242.                 }  
  243.                 return ObjectUtils.toString(msg);  
  244.             }  
  245.   
  246.         };  
  247.         FelEngine e = getEngine();  
  248.         // 添加函数到引擎中。  
  249.         e.addFun(fun);  
  250.         String exp = "hello('fel')";  
  251.         // 解释执行  
  252.         Object eval = e.eval(exp);  
  253.         System.out.println("hello " + eval);  
  254.         // 编译执行  
  255.         Expression compile = e.compile(exp, null);  
  256.         eval = compile.eval(null);  
  257.         System.out.println("hello " + eval);  
  258.     }  
  259.   
  260.     /** 
  261.      *  
  262.      */  
  263.     public static void testCompileX() {  
  264.         FelEngine fel = getEngine();  
  265.         String exp = "单价*数量";  
  266.         final MutableInt index = new MutableInt(0);  
  267.   
  268.         // 数据库中单价列的记录  
  269.         final int[] price = new int[] { 234 };  
  270.         // 数据库中数量列的记录  
  271.         final double[] number = new double[] { 10.9920.999.9 };  
  272.         FelContext context = new AbstractContext() {  
  273.   
  274.             @Override  
  275.             public Object get(String name) {  
  276.                 if ("单价".equals(name)) {  
  277.                     return price[index.intValue()];  
  278.                 }  
  279.                 if ("数量".equals(name)) {  
  280.                     return number[index.intValue()];  
  281.                 }  
  282.                 return null;  
  283.             }  
  284.         };  
  285.         Expression compExp = fel.compile(exp, context);  
  286.         for (int i = 0; i < number.length; i++) {  
  287.             index.setValue(i);  
  288.             Object eval = compExp.eval(context);  
  289.             System.out.println("总价[" + price[i] + "*" + number[i] + "=" + eval  
  290.                     + "]");  
  291.         }  
  292.     }  
  293.   
  294.     /** 
  295.      * 自定义 解释器 
  296.      */  
  297.     public static void userInterpreter() {  
  298.         FelEngine fel = getEngine();  
  299.         String costStr = "成本";  
  300.         FelContext rootContext = fel.getContext();  
  301.         rootContext.set(costStr, "60000");  
  302.         FelNode node = fel.parse(costStr);  
  303.         // 将变量解析成常量  
  304.         node.setInterpreter(new ConstInterpreter(rootContext, node));  
  305.         System.out.println(node.eval(rootContext));  
  306.     }  
  307.   
  308.     /** 
  309.      * 操作符重载,使用自定义解释器实现操作符重载 
  310.      */  
  311.     public static void operatorOverload() {  
  312.         /* 
  313.          * 扩展Fel的+运算符,使其支持数组+数组 
  314.          */  
  315.   
  316.         FelEngine fel = getEngine();  
  317.         // 单价  
  318.         double[] price = new double[] { 234 };  
  319.         // 费用  
  320.         double[] cost = new double[] { 0.30.30.4 };  
  321.         FelContext ctx = fel.getContext();  
  322.         ctx.set("单价", price);  
  323.         ctx.set("费用", cost);  
  324.         String exp = "单价+费用";  
  325.         Interpreters interpreters = new Interpreters();  
  326.         // 定义"+"操作符的解释方法。  
  327.         interpreters.add("+"new Interpreter() {  
  328.             @Override  
  329.             public Object interpret(FelContext context, FelNode node) {  
  330.                 List<FelNode> args = node.getChildren();  
  331.                 double[] leftArg = (double[]) args.get(0).eval(context);  
  332.                 double[] rightArg = (double[]) args.get(1).eval(context);  
  333.                 return sum(leftArg) + sum(rightArg);  
  334.             }  
  335.   
  336.             // 对数组进行求和  
  337.             public double sum(double[] array) {  
  338.                 double d = 0;  
  339.                 for (int i = 0; i < array.length; i++) {  
  340.                     d += array[i];  
  341.                 }  
  342.                 return d;  
  343.             }  
  344.         });  
  345.   
  346.         // 使用自定义解释器作为编译选项进行进行编译  
  347.         Expression expObj = fel.compile(exp, null, interpreters);  
  348.         Object eval = expObj.eval(ctx);  
  349.         System.out.println("数组相加:" + eval);  
  350.     }  
  351.   
  352.     /** 
  353.      * 速度测试 
  354.      */  
  355.     public static void testSpeed() {  
  356.         FelEngine fel = getEngine();  
  357.         String exp = "40.52334+60*(21.8144+17*32.663)";  
  358.         FelNode node = fel.parse(exp);  
  359.         int times = 1000;  
  360.         long s1 = System.currentTimeMillis();  
  361.         for (int i = 0; i < times; i++) {  
  362.             // double j = 40.52334 + 60 * (21.8144 + 17 * 32.663);  
  363.             node.eval(null);  
  364.         }  
  365.         long s2 = System.currentTimeMillis();  
  366.         System.out.println("花费的时间:" + (s2 - s1));  
  367.     }  
  368.   
  369.     /** 
  370.      * 大数据量计算(计算1千万次) 
  371.      */  
  372.     public static void massData() {  
  373.         FelEngine fel = getEngine();  
  374.         final Interpreters opti = new Interpreters();  
  375.         final MutableInt index = new MutableInt(0);  
  376.         int count = 10 * 1000 * 1000;  
  377.         final double[] counts = new double[count];  
  378.         final double[] prices = new double[count];  
  379.         Arrays.fill(counts, 10d);  
  380.         Arrays.fill(prices, 2.5d);  
  381.         opti.add("单价"new Interpreter() {  
  382.             @Override  
  383.             public Object interpret(FelContext context, FelNode node) {  
  384.                 return prices[index.intValue()];  
  385.             }  
  386.         });  
  387.         opti.add("数量"new Interpreter() {  
  388.             @Override  
  389.             public Object interpret(FelContext context, FelNode node) {  
  390.                 return counts[index.intValue()];  
  391.             }  
  392.         });  
  393.         Expression expObj = fel.compile("单价*数量"null, opti);  
  394.         long start = System.currentTimeMillis();  
  395.         Object result = null;  
  396.         for (int i = 0; i < count; i++) {  
  397.             result = expObj.eval(null);  
  398.             index.increment();  
  399.         }  
  400.         long end = System.currentTimeMillis();  
  401.   
  402.         System.out.println("大数据量计算:" + result + ";耗时:" + (end - start));  
  403.     }  
  404.   
  405.     /** 
  406.      * 静态方法 
  407.      *  
  408.      *  
  409.      * 如果你觉得上面的自定义函数也麻烦,Fel提供的$函数可以方便的调用工具类的方法 熟悉jQuery的朋友肯定知道"$"函数的威力。 
  410.      * Fel东施效颦,也实现了一个"$"函数,其作用是获取class和创建对象。结合点操作符,可以轻易的调用工具类或对象的方法。 
  411.      * 通过"$('class').method"形式的语法,就可以调用任何等三方类包(commons lang等)及自定义工具类的方法, 
  412.      * 也可以创建对象,调用对象的方法。如果有需要,还可以直接注册Java Method到函数管理器中。 
  413.      */  
  414.     public static void staticMethod() {  
  415.         // 调用Math.min(1,2)  
  416.         System.out.println(FelEngine.instance.eval("$('Math').max(1,3)"));  
  417.         // 调用new Foo().toString();  
  418.         System.out.println(FelEngine.instance  
  419.                 .eval("$('com.ebiz.fel.Foo.new').toString()"));  
  420.     }  
  421.   
  422.     private static FelEngine getEngine() {  
  423.         return FelBuilder.engine();  
  424.     }  
  425.   
  426. }  
  427.   
  428. class ColumnInterpreter implements Interpreter {  
  429.     MutableInt index;  
  430.   
  431.     double[] records;  
  432.   
  433.     ColumnInterpreter(MutableInt index, double[] records) {  
  434.         this.index = index;  
  435.         this.records = records;  
  436.     }  
  437.   
  438.     @Override  
  439.     public Object interpret(FelContext context, FelNode node) {  
  440.         return records[index.intValue()];  
  441.     }  
  442. }  
  443.   
  444. class MutableInt {  
  445.     private int value;  
  446.   
  447.     public MutableInt(int i) {  
  448.         this.value = i;  
  449.     }  
  450.   
  451.     public int intValue() {  
  452.         return value;  
  453.     }  
  454.   
  455.     public void setValue(int i) {  
  456.         this.value = i;  
  457.     }  
  458.   
  459.     public void increment() {  
  460.         value++;  
  461.     }  
  462. }  

Foo类:

[java]   
  1. import java.util.ArrayList;  
  2. import java.util.Iterator;  
  3. import java.util.List;  
  4.   
  5. public class Foo {  
  6.   
  7.     private final String name;  
  8.   
  9.     private Foo foo = null;  
  10.   
  11.     static private Foo[] f = new Foo[] { new Foo("array0"), new Foo("array1") };  
  12.   
  13.     static private Foo[] fooes = f;  
  14.   
  15.     public Foo[] getFooes() {  
  16.         return fooes;  
  17.     }  
  18.   
  19.     public void setFooes(Foo[] fooes) {  
  20.         this.fooes = fooes;  
  21.     }  
  22.   
  23.     private boolean beenModified = false;  
  24.     private String property1 = "some value";  
  25.   
  26.     public Foo(String name) {  
  27.         this.name = name;  
  28.     }  
  29.   
  30.     public Foo() {  
  31.         this("anonymity");  
  32.     }  
  33.   
  34.     public static String sayHello(String str) {  
  35.         return "hello" + str;  
  36.     }  
  37.   
  38.     public class Cheezy {  
  39.         public Iterator<String> iterator() {  
  40.             return getCheeseList().iterator();  
  41.         }  
  42.     }  
  43.   
  44.     public String get(String arg) {  
  45.         if ("name".equals(arg)) {  
  46.             return name;  
  47.         }  
  48.         return "can't find " + arg;  
  49.     }  
  50.   
  51.     public String convertBoolean(boolean b) {  
  52.         return "Boolean : " + b;  
  53.     }  
  54.   
  55.     public int getCount() {  
  56.         return 5;  
  57.     }  
  58.   
  59.     public String contact(String a, String b, String c, String d) {  
  60.         return a + b + c + c;  
  61.     }  
  62.   
  63.     public List<String> getCheeseList() {  
  64.         ArrayList<String> answer = new ArrayList<String>();  
  65.         answer.add("cheddar");  
  66.         answer.add("edam");  
  67.         answer.add("brie");  
  68.         return answer;  
  69.     }  
  70.   
  71.     public Cheezy getCheezy() {  
  72.         return new Cheezy();  
  73.     }  
  74.   
  75.     public boolean isSimple() {  
  76.         return true;  
  77.     }  
  78.   
  79.     public int square(int value) {  
  80.         return value * value;  
  81.     }  
  82.   
  83.     public boolean getTrueAndModify() {  
  84.         beenModified = true;  
  85.         return true;  
  86.     }  
  87.   
  88.     public boolean getModified() {  
  89.         return beenModified;  
  90.     }  
  91.   
  92.     public int getSize() {  
  93.         return 22;  
  94.     }  
  95.   
  96.     public String getProperty1() {  
  97.         return property1;  
  98.     }  
  99.   
  100.     public void setProperty1(String newValue) {  
  101.         property1 = newValue;  
  102.     }  
  103.   
  104.     public Foo getFoo() {  
  105.         return this.foo;  
  106.     }  
  107.   
  108.     public void setFoo(Foo foo) {  
  109.         this.foo = foo;  
  110.     }  
  111.   
  112.     @Override  
  113.     public String toString() {  
  114.         return this.name;  
  115.     }  
  116. }  
运行结果:

[java]   
  1. -----------1.入门---------  
  2. 67500  
  3. -----------2.使用变量---------  
  4. 67500  
  5. -----------3.获取对象属性---------  
  6. 22  
  7. can't find sample  
  8. anonymity  
  9. fel  
  10. ---------4.调用对象的方法-----------  
  11. Everybody  
  12. --------5.访问数组、集合------------  
  13. intArray[0]->1  
  14. list[0]->1  
  15. coll[0]->a  
  16. iterator[0]->a  
  17. map.name->Wangxiaoming  
  18. intArrays[0][0]->11  
  19. listArray[0][0]->1  
  20. --------6.自定义上下文环境------------  
  21. 天气-----:晴;温度------:25  
  22. --------7.多层次上下文环境(变量命名空间)------------  
  23. 期望利润:50  
  24. 实际利润:30  
  25. ---------8.大数值计算-----------  
  26. 大数值计算(解释执行):22333333333333333333333333333333  
  27. 大数值计算(编译执行):22333333333333333333333333333333  
  28. ----------9.函数----------  
  29. hello fel  
  30. hello fel  
  31. ---------10.自定义 解释器-----------  
  32. 60000  
  33. ----------11.操作符重载----------  
  34. 数组相加:10.0  
  35. ----------12.速度测试----------  
  36. 花费的时间:91  
  37. ----------13.静态方法----------  
  38. 3  
  39. anonymity  

转载地址:http://mdlnn.baihongyu.com/

你可能感兴趣的文章
软件工程homework----九宫格记忆网
查看>>
MyBatis笔记_第一部分(狂神老师的笔记)
查看>>
IDEA2020连接mysql8.0时时区问题的解决方法
查看>>
2021-06-09安卓项目图片
查看>>
C语言小游戏——井字棋
查看>>
软件测试基础
查看>>
测试模型
查看>>
杯子测试点
查看>>
测试点
查看>>
测试面试题
查看>>
Flutter学习第六天:Flutter实现打开第三方应用、一行代码实现夜间模式、字体改变、跟随手指移动,加载网络图片等功能。
查看>>
Java+selenium自动化测试无法登陆http://localhost/phpwind/index.php网站的问题?
查看>>
Flutter学习第十五天:2021年最新版超详细Flutter实现Mob+SMSSDK手机验证码登录实现,Android和Flutter混合开发?
查看>>
flutter百度语音唤醒功能出现 {“error“:11,“desc“:“Wakeup engine has no license“,“sub_error“:11002}怎么办?
查看>>
数据结构第二章--栈和队列的考点(输出序列、前缀和后缀、中缀之间转换以及求值,循环队列问题,双端队列),以及实现功能代码?
查看>>
带你实现HarmonyOS的DevEco Studio编译器的安装和简单使用教程,实现创建并运行hello world?
查看>>
【建议收藏】数据结构考研常用的8种排序算法
查看>>
【思维导图】数据结构考研常用的5种查找
查看>>
Error while building/deploying project QSerialPort_1 (kit: Desktop Qt 5.4.0 MinGW 32bit)
查看>>
纵表和横表的相互转换与自我理解
查看>>