• fel基本使用


    fel 我猜 是  function expression language 的缩写,函数表达式语言

    使用:引入maven依赖(据说有0.9支持大整数 但是 maven 仓库没有 )

    		<!-- fel -->
    		 <dependency>
    		    <groupId>org.eweb4j</groupId>
    		    <artifactId>fel</artifactId>
    		    <version>0.8</version>
    		</dependency>
    		
    

      

     

    测试和使用说明:

    package com.lomi.fel;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Collection;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    
    import org.junit.Test;
    
    import com.alibaba.fastjson.JSONObject;
    import com.greenpineyu.fel.Expression;
    import com.greenpineyu.fel.FelEngine;
    import com.greenpineyu.fel.FelEngineImpl;
    import com.greenpineyu.fel.common.ObjectUtils;
    import com.greenpineyu.fel.context.AbstractContext;
    import com.greenpineyu.fel.context.ContextChain;
    import com.greenpineyu.fel.context.FelContext;
    import com.greenpineyu.fel.context.MapContext;
    import com.greenpineyu.fel.function.CommonFunction;
    import com.greenpineyu.fel.function.Function;
    import com.greenpineyu.fel.parser.FelNode;
    import com.lomi.entity.Goods;
    
    public class FelTest {
    
    	
    	/**
    	 * 使用常量
    	 */
    	@Test
    	public void test0() {
    		FelEngine felEngine = new FelEngineImpl();
    		Object result = felEngine.eval("2*3");
    		System.out.println(result);
    	}
    	
    
    	/**
    	 * 使用变量
    	 */
    	@Test
    	public void test2() {
    		FelEngine felEngine = new FelEngineImpl();
    		FelContext ctx = felEngine.getContext();
    		ctx.set("count", 10);
    		ctx.set("price", 100);
    		Object result = felEngine.eval("count*price");
    		System.out.println(result);
    	}
    
    	/**
    	 * 使用变量的方法和属性
    	 */
    	@Test
    	public void test3() {
    		FelEngine felEngine = new FelEngineImpl();
    		FelContext ctx = felEngine.getContext();
    		Goods good = Goods.randomGoods();
    		ctx.set("good", good);
    		
    		Map<String, String> map = new HashMap<String, String>();
    		map.put("key1", "value1");
    		ctx.set("map", map);
    
    		//取不存在的方法属性,返回null
    		Object result = felEngine.eval("good.size");
    		System.out.println("result:" + result);
    
    		//调用good的toString
    		result = felEngine.eval("good.toString");
    		System.out.println("result:" + result);
    
    		//获取name(分别调用  name() 方法 和  getName() 方法,name(优先) ,不会取直接获取私有字段)
    		result = felEngine.eval("good.name");
    		System.out.println("result:" + result);
    		
    		//调用有参方法  name(int  i) 
    		result = felEngine.eval("good.name(1)");
    		System.out.println("result:" + result);
    		
    
    		//获取 map 的 value
    		result = felEngine.eval("map.key1");
    		System.out.println("result:" + result);
    	}
    
    	/**
    	 * 使用集合,直接用下标获取 集合元素
    	 */
    	@Test
    	public void test4() {
    		FelEngine felEngine = new FelEngineImpl();
    		FelContext ctx = felEngine.getContext();
    
    		// 数组
    		int[] intArray = { 1, 2, 3 };
    		ctx.set("intArray", intArray);
    		String exp = "intArray[0]";
    		System.out.println(exp + "->" + felEngine.eval(exp));
    
    		// List
    		List<Integer> list = Arrays.asList(1, 2, 3);
    		ctx.set("list", list);
    		exp = "list[0]";
    		System.out.println(exp + "->" + felEngine.eval(exp));
    
    		// 集合
    		Collection<String> coll = Arrays.asList("a", "b", "c");
    		ctx.set("coll", coll);
    		// 获取集合最前面的元素。执行结果为"a"
    		exp = "coll[0]";
    		System.out.println(exp + "->" + felEngine.eval(exp));
    
    		// 迭代器
    		Iterator<String> iterator = coll.iterator();
    		ctx.set("iterator", iterator);
    		// 获取迭代器最前面的元素。执行结果为"a"
    		exp = "iterator[0]";
    		System.out.println(exp + "->" + felEngine.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 + "->" + felEngine.eval(exp));
    
    		// 多维数组
    		int[][] intArrays = { { 11, 12 }, { 21, 22 } };
    		ctx.set("intArrays", intArrays);
    		exp = "intArrays[0][0]";
    		System.out.println(exp + "->" + felEngine.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 + "->" + felEngine.eval(exp));
    	}
    
    	/**
    	 * 使用类的静态方法和new
    	 */
    	@Test
    	public void test5() {
    		FelEngine fel = new FelEngineImpl();
    		FelContext ctx = fel.getContext();
    		ctx.set("json", JSONObject.class);
    		ctx.set("goods", Goods.randomGoods());
    
    		System.out.println(fel.eval("json.toJSONString( goods )"));
    		
    		
    		
    		// 调用Math.min(1,2),java.lang包下面的都可简写
    		System.out.println(FelEngine.instance.eval("$('Math').min(1,2)"));
    		
    		// 调用new Goods().randomGoods();
    		System.out.println(FelEngine.instance.eval("$('com.lomi.entity.Goods.new').randomGoods()"));
    		
    		//感觉这玩意可以用链式编程动态编程(如果不考虑效率的话)
    		ctx.set("name1", "张三");
    		System.out.println(FelEngine.instance.eval("$('com.lomi.entity.Goods.new').setName(name1)",ctx));
    		
    		
    	}
    
    	/**
    	 * 使用上下文的参数
    	 */
    	@Test
    	public void test6() {
    		// 负责提供气象服务的上下文环境
    		FelContext ctx = new AbstractContext() {
    			public Object get(String name) {
    				if ("天气".equals(name)) {
    					return "晴";
    				}
    				if ("温度".equals(name)) {
    					return 25;
    				}
    				return null;
    			}
    		};
    		
    		
    		
    		FelEngine felEngine = new FelEngineImpl(ctx);
    		Object eval = felEngine.eval("'天气:'+天气+';温度:'+温度");
    		System.out.println(eval);
    	}
    
    	/**
    	 * 多层上下文(有继承关系,新的覆盖老的重复值)
    	 */
    	@Test
    	public void test7() {
    		FelEngine felEngine = new FelEngineImpl();
    		
    		FelContext ctx1 = felEngine.getContext();
    		ctx1.set("a", 10);
    		ctx1.set("b", 100);
    		
    		
    		FelContext ctx2 = new ContextChain(ctx1, new MapContext());
    		ctx2.set("a", 20);
    		
    		
    		String exp = "b" + "-" + "a";
    		
    		
    		//使用上下文2
    		Object rt2 = felEngine.eval(exp, ctx2);
    		System.out.println("b-a=" + rt2);
    		
    		
    		//使用上下文1
    		Object rt = felEngine.eval(exp);
    		System.out.println("b-a=" + rt);
    
    	}
    
    	/**
    	 * 编译以后在执行效率会高很多(先编译后执行,前提是公式固定)
    	 */
    	@Test
    	public void test8() {
    		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);
    	}
    
    	/**
    	 * 大值(不知道哪里有0.9的版本)
    	 */
    	@Test
    	public void test9() {
    		/*
    		 * 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);
    		 */
    	}
    	
    	/**
    	 * 子定义函数
    	 */
    	@Test
    	public void test11() {
    	    Function fun = new CommonFunction() {   
    	        public String getName() {   
    	            return "hello";   
    	        }   
    	        @Override   
    	        public Object call(Object[] arguments) {   
    	            Object msg = null;   
    	            if(arguments!= null && arguments.length>0){   
    	                msg = arguments[0];   
    	            }   
    	            
    	            System.out.println( msg );
    	            
    	            return "say:" + ObjectUtils.toString(msg);   
    	        }   
    	    };  
    	    
    	    
    	    Function addFun = new CommonFunction() {   
    	        public String getName() {   
    	            return "add";   
    	        }   
    	        @Override   
    	        public Object call(Object[] arguments) {   
    	        	if(arguments== null || arguments.length != 2){   
    	              throw new RuntimeException("参数异常");
    	            }   
    	        	
    	        	int a = (int)arguments[0];
    	        	int b = (int)arguments[1];
    	            return a+b;   
    	        }   
    	    };  
    	    
    	    
    	    
    	    FelEngine felEngine = new FelEngineImpl();   
    	    //添加函数到引擎中。   
    	    felEngine.addFun(fun);   
    	    felEngine.addFun(addFun);
    	    
    	    
    	    String exp = "hello('你好')";   
    	    //解释执行   
    	    Object eval = felEngine.eval(exp);   
    	    System.out.println("hello "+eval);   
    	    
    	    
    	    //编译执行(编译的过程会直接执行一边,如果这时候 修改了 上下文的变量,就要注意了)
    	    Expression compile = felEngine.compile(exp, null);   
    	    eval = compile.eval(null);   
    	    System.out.println("hello "+eval);
    	    
    	    
    	    //函数里面可以套函数( CommonFunction.call.(Object[] arguments) 方法里面拿到的都是已经吧内嵌函数计算好了,详情见父类的 CommonFunction.call(FelNode node, FelContext context) )
    	    System.out.println( felEngine.eval("hello( add(3,2) )") );
    	}
    	
    	
    	
    	
    	/**
    	 * 效率比较,正常简单相加20亿次,5秒
    	 */
    	@Test
    	public void test12() {
    		
    		Long start = System.currentTimeMillis();
    		Integer a = 0;
    		Add add = new Add();
    		for(int i = 0;i<2000000000;i++) {
    			a= (Integer) add.call( new Integer[] {a,1} );
    		}
    		Long end = System.currentTimeMillis();
    		System.out.println( a );
    		System.out.println( end-start );
    	}
    	
    	/**
    	 * 解释执行也就差5000 倍,10W次6 秒。
    	 */
    	@Test
    	public void test13() {
    		
    		Long start = System.currentTimeMillis();
    		FelEngine felEngine = new FelEngineImpl();   
    		felEngine.addFun( new Add() );
    		Integer a = 0;
    		for(int i = 0;i<1000000;i++) {
    			a = (Integer) felEngine.eval("add("+ a +",1)");
    		}
    		Long end = System.currentTimeMillis();
    		System.out.println( a );
    		System.out.println( end-start );
    	}
    	
    	
    	/**
    	 * 解释执行也就差10多20 倍,2亿次9 秒
    	 */
    	@Test
    	public void test14() {
    		
    		Long start = System.currentTimeMillis();
    		FelEngine felEngine = new FelEngineImpl();   
    		felEngine.addFun( new Add2() );
    		Object a = 0;
    		FelContext felContext = felEngine.getContext();
    		felContext.set("a", 0 );
    		
    		//不知道为啥编译会把int类型改成double。
    		Expression expression  = felEngine.compile("add(a,1)",felContext);
    		
    		for(int i = 0;i<200000000;i++) {
    			a =  expression.eval(felContext);
    		}
    		
    		Long end = System.currentTimeMillis();
    		System.out.println( a );
    		System.out.println( end-start );
    	}



        

          /**
          * 覆盖 com.greenpineyu.fel.function.operator 下面的 +,-,*,/,=,等可以从定义这些符号,比如让 1==2 返回true
          */
          @Test
            public void testEqual() {
            FelEngine felEngine = new FelEngineImpl();

            Object evalRt = felEngine.eval("1==2");
            System.out.println( evalRt );

          }

    	
    	
    	class Add extends CommonFunction{
    		@Override
    		public String getName() {
    			return "add";
    		}
    
    		@Override
    		public Object call(Object[] arguments) {
    			return (Integer)arguments[0] + (Integer)arguments[1];
    		}
    	}
    	
    	class Add2 extends CommonFunction{
    		FelContext context;
    		
    		public Object call(FelNode node, FelContext context) {
    			Object[] children = evalArgs(node, context);
    			this.context = context;
    			return call(children);
    		}
    		
    		
    		@Override
    		public String getName() {
    			return "add";
    		}
    
    		@Override
    		public Integer call(Object[] arguments) {
    			Integer a = (Integer)arguments[0] + (Integer)arguments[1];
    			context.set("a", a);
    			return a;
    		}
    	}
    	
    	
    	
    	
    	
    	
    	
    
    }
    

      

    附Goods类:

    package com.lomi.entity;
    
    import com.lomi.utils.CodeUtil;
    
    import cn.hutool.core.util.IdUtil;
    
    public class Goods {
        private Long id;
    
        private String name;
    
        private Integer stock;
    
        private String des;
    
        private String data;
        
        public Goods( String name ) {
        	this.name = name;
        }
        public Goods() {}
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
        
        public String name(int  i) {
            return "name方法" + i;
        }
    
        public Goods setName(String name) {
            this.name = name == null ? null : name.trim();
            return this;
        }
    
        public Integer getStock() {
            return stock;
        }
    
        public void setStock(Integer stock) {
            this.stock = stock;
        }
    
        public String getDes() {
            return des;
        }
    
        public void setDes(String des) {
            this.des = des == null ? null : des.trim();
        }
    
        public String getData() {
            return data;
        }
    
        public void setData(String data) {
            this.data = data == null ? null : data.trim();
        }
        
        
        
        
    	  
        @Override
    	public String toString() {
    		return "Goods [id=" + id + ", name=" + name + ", stock=" + stock + ", des=" + des + ", data=" + data + "]";
    	}
        
        
    	public static Goods randomGoods() {
        	Goods goods = new Goods();
    		goods.setId(IdUtil.getSnowflakeNextId());
    		goods.setData(  CodeUtil.getRandomNum18() );
    		goods.setDes( CodeUtil.randomCode(6) );
    		goods.setName( CodeUtil.randomCode(3) );
    		goods.setStock( Integer.valueOf( CodeUtil.randomNumCode(4) ) );
    		
        	return goods;
        }
    	
    	public static void main(String[] args) {
    		 System.out.println( Long.MAX_VALUE ); 
    	}
        
    }
    

      

    例子地址代码:https://github.com/hualiuwuxin/TestExample.git

  • 相关阅读:
    在ubuntu系统使用SSR
    Pandas库
    Numpy
    06-Python之标准库
    do{}while(0)
    inet_XX族函数
    大端小端
    c++ 强制类型转换
    auto类型推导
    const浅析
  • 原文地址:https://www.cnblogs.com/cxygg/p/16077661.html
Copyright © 2020-2023  润新知