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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM