专栏首页Java学习资料利用ScriptEngineManager实现字符串公式灵活计算
原创

利用ScriptEngineManager实现字符串公式灵活计算

在开发中我们可能会出现大量的公式计算,而这些公式可能并不确定。

比如用户今天说a=b+c 然而下次说公式不正确 应该是a=d+e

如果单纯的在代码中把这些公式写死 实现,后期修改维护工作量显然会增加好多。

下面就简单的介绍一种实现方法的思路:

我们知道js的eval()方法可以执行字符串的代码 而恰好jdk6增加了对脚本语言的支持 我们可以利用这个特性对计算实现简单化的处理 

下面举个例子

例如有个公式  A+B*C  其中A=1,B=2,C=3

我们可以将公式的A B C替换成数字 转换为 1+2*3 最后就可以得到结果了

刚刚接触到ScriptEngine这个东西的时候仅仅了解其eval()方法 ,于是我利用了上述例子的思路去实现将字母替换成相应的数字去得到数字公式进而得到运算结果。

那么替换的方法当然是用正则去替换了,java中String对象有个replaceAll()方法可以实现。

当时想这个正则可是琢么了一会儿呢。然而我这种实现却白忙活了,因为后期发现没有必要这么麻烦

具体怎么实现大家可以想想看,我就不具体介绍了,有了思路比什么都重要。

然而过了一段时间,我在面试的时候和一个前辈聊天时,前辈告诉我不用自己写正则去替换,js中本来就有对象,也支持对象的运算,所以直接往里放对象就可以。

后来我自己查了查资料,发现果然可以:

为了可以实现打印出中间参与计算的变量,我利用反射实现了获取值的方法

下面就是代码的实现:

    public static void Calculation(){         Student stu=new Student();         stu.setAge(10);         stu.setName("zhangsan");         stu.setSex(false);

        // 上边是student对象

        Class claz=stu.getClass();         String className= claz.getSimpleName();         //String formula="Student.name+Student.age+10";  //1         String formula="function test(){ if(Student.age==10){ return 12;} }"; //2         System.out.println("the formula is:"+formula);

        //获取对象名称和值         for(Field field: claz.getDeclaredFields()){             try {                 //打开私有访问                 //field.setAccessible(true);                 String fieldName = field.getName();                 Method m = (Method) claz.getMethod("get" +getMethodName(fieldName));                   System.out.println(getMethodName(fieldName));                 System.out.println(field.getGenericType()+"-"+"fieldName:"+fieldName+"="+m.invoke(stu));             } catch (Exception e) {                 e.printStackTrace();             }          }         Object result=null;  //计算结果         ScriptEngineManager manager = new ScriptEngineManager();   //创建一个ScriptEngineManager对象         ScriptEngine engine = manager.getEngineByName("js");  //通过ScriptEngineManager获得ScriptEngine对象         engine.put(className, stu);  //将student对象放到ScriptEngine 中为计算变量提供值         try {             //result =engine.eval(formula);  //1 用ScriptEngine的eval方法执行脚本  String formula="Student.name+Student.age+10";

            engine.eval(formula);            //2             Invocable inv = (Invocable) engine; //2             result=inv.invokeFunction("test");  //2   执行字符串 js test()             System.out.println("the result is :"+result.toString());         } catch (Exception e) {             System.out.println("错误");             e.printStackTrace();         }      }      // 把一个字符串的第一个字母大写       private static String getMethodName(String fildeName) throws Exception{                byte[] items = fildeName.getBytes();                items[0] = (byte) ((char) items[0] - 'a' + 'A');                return new String(items);        }

上述代码 还可注释2 打开注释1 试试 一样可以的 不过方式不同而已 

有了这个思想 我们就可以把公式维护到数据库或文件中 方便我们后期对公式的维护修改 这样利用这个工具应该可以减少计算代码编写的复杂度 

后期我也发现了好多表达式引擎如:Aviator、IKExpression等。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 接口中的几种限流实现

    这些情况都是无法预知的,不知道什么时候会有10倍甚至20倍的流量进来,如果遇到此类情况,扩容是根本来不及的,弹性扩容也是来不及的;

    动力节点Java学院
  • 接口中的几种限流实现

    这些情况都是无法预知的,不知道什么时候会有10倍甚至20倍的流量进来,如果遇到此类情况,扩容是根本来不及的,弹性扩容也是来不及的;

    动力节点Java学院
  • Java单例设计模式的理解与常规实现方式

          单例类必须自己创建自己的唯一实例。 单例类必须给所有其他对象提供这一实例。

    动力节点Java学院
  • 对的时间遇到对的课

    同学们好! 《计算机视觉原理及实战》已经开播两节拉! 内容新颖有趣,范例源自生活 好奇宝宝们请戳下面的节选see see~ ▼ ?

    AI科技大本营
  • 我在爱奇艺实习的八个月

    记得去年暑假伊始,在那个炎热的午后,我带着懵懂来到上海面试,如今掐指一算,我已经在公司工作了八个多月。在这段时间里,我在工作上认识了很多前辈,生活中也结交了不少...

    好好学java
  • 周志华西瓜书详细公式推导,Datawhale开源pumpkin-book项目

    如果让你推荐两本国内机器学习的入门经典作,你会推荐哪些呢?相信大家同我一样,非李航的《统计学习方法》和周志华的《机器学习》莫属。

    机器之心
  • 坦然面对:应对前端疲劳

    我最近和一个做后端开发的朋友讨论我在工作之余花了多长的时间去写码和学习写码。他给我看了Uncle Bob的《Clean Code》这本书中的一段话,它将音乐家们...

    前朝楚水
  • 《深度学习Ng》课程学习笔记02week2——优化算法

    http://blog.csdn.net/u011239443/article/details/78066082 2.1 Mini-batch 梯度下降法 ? ...

    用户1621453
  • 【行业】Fontcode算法可以找出隐藏在正常文本中的秘密消息

    AiTechYun 编辑:nanan ? 无论是将秘密隐藏在信件的邮票下面还是用隐形墨水书写,人们总能找到一些巧妙的方法,利用他们懂得的技术来编写秘密信息。哥伦...

    AiTechYun
  • 疯狂暴涨曾破 2 万美元的比特币,到底是怎么一回事?

    2017 年对比特币来说,是极为疯狂的一年。年初,一枚比特币的价格不到 1,000 美元。在 11 月价格持续突破 8,000、9,000 和 10,000 美...

    企鹅号小编

扫码关注云+社区

领取腾讯云代金券