zoukankan      html  css  js  c++  java
  • Fel是轻量级的高效的表达式计算引擎学习(一)

    Fel在源自于企业项目,设计目标是为了满足不断变化的功能需求和性能需求。

    Fel是开放的,引擎执行中的多个模块都可以扩展或替换。Fel的执行主要是通过函数实现,运算符(+、-等都是Fel函数),所有这些函数都是可以替换的,扩展函数也非常简单。
    Fel有双引擎,同时支持解释执行和编译执行。可以根据性能要求选择执行方式。编译执行就是将表达式编译成字节码(生成java代码和编译模块都是可以扩展和替换的)

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

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

    具体的测试数据请参见http://code.google.com/p/fast-el/wiki/Performance。

    为何要使用Fel?
    Fel语法和API非常简单,语法与Java基本相同,几乎没有学习成本。

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

    Fel整个包只有200多KB。

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

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

    Fel支持大数值高精度计算

    Fel有良好的安全管理功能

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

    Fel不能做什么?
    Fel只支持表达式,不支持脚本。

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

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


    安装
    1:获取Fel
    项目主页:http://code.google.com/p/fast-el/ 下载地址:http://code.google.com/p/fast-el/downloads/list


    Fel使用例子:
    1:算术表达式:

    FelEngine fel = new FelEngineImpl();    
    Object result = fel.eval("5000*12+7500");    
    System.out.println(result); 

    输出结果:67500

    2:变量

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

    FelContext ctx = fel.getContext();    
    ctx.set("单价", 5000);    
    ctx.set("数量", 12);    
    ctx.set("运费", 7500);    
    Object result = fel.eval("单价*数量+运费");    
    System.out.println(result); 

    输出结果:67500

    3:访问对象属性

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

    FelEngine fel = new FelEngineImpl();
    FelContext ctx = fel.getContext();
    Foo foo = new Foo();
    ctx.set("foo", foo);
    Map<String,String> m = new HashMap<String,String>();
    m.put("ElName", "fel");
    ctx.set("m",m);
            
    //调用foo.getSize()方法。
    Object result = fel.eval("foo.size");
     
    //调用foo.isSample()方法。
    result = fel.eval("foo.sample");
                    
    //foo没有name、getName、isName方法
    //foo.name会调用foo.get("name")方法。
    result = fel.eval("foo.name");
                    
    //m.ElName会调用m.get("ElName");
    result = fel.eval("m.ElName");

    4:访问数组、集合、Map

    FelEngine fel = new FelEngineImpl();
    FelContext ctx = fel.getContext();
     
    //数组
    int[] intArray = {1,2,3};
    ctx.set("intArray",intArray);
    //获取intArray[0]
    String exp = "intArray[0]";
    System.out.println(exp+"->"+fel.eval(exp));
     
    //List
    List<Integer> list = Arrays.asList(1,2,3);
    ctx.set("list",list);
    //获取list.get(0)
    exp = "list[0]";
    System.out.println(exp+"->"+fel.eval(exp));
     
    //集合
    Collection<String> coll = Arrays.asList("a","b","c");
    ctx.set("coll",coll);
    //获取集合最前面的元素。执行结果为"a"
    exp = "coll[0]";
    System.out.println(exp+"->"+fel.eval(exp));
     
    //迭代器
    Iterator<String> iterator = coll.iterator();
    ctx.set("iterator", iterator);
    //获取迭代器最前面的元素。执行结果为"a"
    exp = "iterator[0]";
    System.out.println(exp+"->"+fel.eval(exp));
     
    //Map
    Map<String,String> m = new HashMap<String, String>();
    m.put("name", "HashMap");
    ctx.set("map",m);
    exp = "map.name";
    System.out.println(exp+"->"+fel.eval(exp));
     
    //多维数组
    int[][] intArrays= {{11,12},{21,22}};
    ctx.set("intArrays",intArrays);
    exp = "intArrays[0][0]";
    System.out.println(exp+"->"+fel.eval(exp));
     
    //多维综合体,支持数组、集合的任意组合。
    List<int[]> listArray = new ArrayList<int[]>();
    listArray.add(new int[]{1,2,3});
    listArray.add(new int[]{4,5,6});
    ctx.set("listArray",listArray);
    exp = "listArray[0][0]";
    System.out.println(exp+"->"+fel.eval(exp));

    5:调用JAVA方法

    FelEngine fel = new FelEngineImpl();   
    FelContext ctx = fel.getContext();   
    ctx.set("out", System.out);   
    fel.eval("out.println('Hello Everybody'.substring(6))");  

    输出结果:Everybody

    6:自定义上下文环境

    //负责提供气象服务的上下文环境   
    FelContext ctx = new AbstractConetxt() {   
        public Object get(Object name) {   
            if("天气".equals(name)){   
                return "晴";   
            }   
            if("温度".equals(name)){   
                return 25;   
            }   
            return null;   
        }   
    };   
    FelEngine fel = new FelEngineImpl(ctx);   
    Object eval = fel.eval("'天气:'+天气+';温度:'+温度");   
    System.out.println(eval);  

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

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

    FelEngine fel = new FelEngineImpl();   
    String costStr = "成本";   
    String priceStr="价格";   
    FelContext baseCtx = fel.getContext();   
    //父级上下文中设置成本和价格   
    baseCtx.set(costStr, 50);   
    baseCtx.set(priceStr,100);   
       
    String exp = priceStr+"-"+costStr;   
    Object baseCost = fel.eval(exp);   
    System.out.println("期望利润:" + baseCost);   
       
    FelContext ctx = new ContextChain(baseCtx, new MapContext());   
    //通货膨胀导致成本增加(子级上下文 中设置成本,会覆盖父级上下文中的成本)   
    ctx.set(costStr,50+20 );   
    Object allCost = fel.eval(exp, ctx);   
    System.out.println("实际利润:" + allCost);  

    输出结果:

    期望利润:50

    实际利润:30

    8:编译执行

    FelEngine fel = new FelEngineImpl();   
    FelContext ctx = fel.getContext();   
    ctx.set("单价", 5000);   
    ctx.set("数量", 12);   
    ctx.set("运费", 7500);   
    Expression exp = fel.compile("单价*数量+运费",ctx);   
    Object result = exp.eval(ctx);   
    System.out.println(result);  

    执行结果:67500

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

    9:自定义函数

        //定义hello函数   
        Function fun = new CommonFunction() {   
      
            public String getName() {   
                return "hello";   
            }   
               
            /*   
             * 调用hello("xxx")时执行的代码  
             */   
            @Override   
            public Object call(Object[] arguments) {   
                Object msg = null;   
                if(arguments!= null && arguments.length>0){   
                    msg = arguments[0];   
                }   
                return ObjectUtils.toString(msg);   
            }   
      
        };   
        FelEngine e = new FelEngineImpl();   
        //添加函数到引擎中。   
        e.addFun(fun);   
        String exp = "hello('fel')";   
        //解释执行   
        Object eval = e.eval(exp);   
        System.out.println("hello "+eval);   
        //编译执行   
        Expression compile = e.compile(exp, null);   
        eval = compile.eval(null);   
        System.out.println("hello "+eval);  

    执行结果:

    hello fel hello fel

    10:调用静态方法

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

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

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

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

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

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

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

    安全(始于0.8版本)

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

    Example类:

      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 = { 1, 2, 3 };
    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(1, 2, 3);
    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 = { { 11, 12 }, { 21, 22 } };
    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[] { 1, 2, 3 });
    155         listArray.add(new int[] { 4, 5, 6 });
    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[] { 2, 3, 4 };
    270         // 数据库中数量列的记录
    271         final double[] number = new double[] { 10.99, 20.99, 9.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[] { 2, 3, 4 };
    319         // 费用
    320         double[] cost = new double[] { 0.3, 0.3, 0.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类:

      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 }

    运行结果:

     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

    转载:https://blog.csdn.net/chichengjunma/article/details/56012272

  • 相关阅读:
    微信坚硬的后脚跟
    [项目整理]Win32,MFC的可执行文件只能运行一次
    美司法部索要维基解密志愿者谷歌账户内容
    QML性能
    OSGi 的核心配置、动态化及问题
    OSGi 的由来和本质特性
    机器视觉与计算机视觉
    人工智能与深度学习
    活着就能改变世界
    选择与执行
  • 原文地址:https://www.cnblogs.com/xianfengzhike/p/10233521.html
Copyright © 2011-2022 走看看