Groovy超強的Java動態計算能力

動態計算

應用中可能會遇到一些自定義公式功能, 好比,用戶可能自定義輸入一些公式 a +b, a%2, '000'+s.substr(0,3), 若是你對這樣的需求比較頭痛, 請往下看吧, 咱們立刻解決.java

Groovy

groovy是一種基於JVM的敏捷開發語言, 代碼可以和java很好的結合, groovy 還可使用java的類型, 是否是能力超強, 基本上你想到的均可以解決.shell

如何使用GroovyShell

在使用GroovyShell以前,先Importapp

import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import groovy.lang.Script;

先看看下面的例子:ide

GroovyShell shell = new GroovyShell();

        Object result = shell.evaluate("(1+5)/2");

        System.out.println(result);

這麼簡單的示例, 相信你們都不會出錯, 咱們繼續深刻函數

綁定參數

實際應用中公式{ (a+b)/2 }是用戶定義的, 值是應用系統中的數值, 好比系統中的當前a=1, b=5, 如何將值綁定給公式呢, 一切看代碼ui

Binding binding = new Binding();
        binding.setVariable("p",3.1415926);
        binding.setVariable("r",5);

        GroovyShell shell = new GroovyShell(binding);

        Object result = shell.evaluate("p*r*r");

        System.out.println(result);

        result: 78.539815

引用數學函數

Java中的數學函數不少, 見Math.xxx, 上面的計算結果由於小數位太長, 咱們需求四捨五入, 能夠直接用Math.round,lua

Object result = shell.evaluate("Math.round(p*r*r)");

        System.out.println(result);

        result: 79

這時候的結果可能並不滿意, 咱們須要保留2位小數, 這時候Math.xxx其實並無這樣的函數直接拿來即用, groovy代碼多是這麼寫的:code

import java.math.RoundingMode

        def result = 78.539815
        BigDecimal bg = new BigDecimal(result)
        bg.setScale(2,RoundingMode.HALF_DOWN).doubleValue()

要是可以將上面的代碼寫成一個function, 直接調用那就簡單多了...ip

自定義函數

自定義函數, 這個其實能夠的, 咱們先建立一個Java Classci

public class EvalBaseScript extends Script {

    @Override
    public Object run() {
        Method[] methods = EvalBaseScript.class.getDeclaredMethods();
        StringBuilder sb=new StringBuilder();
        for (Method method : methods) {
            sb.append(method);
        }

        return sb.substring(0, sb.length()-1);
    }

    public static double round(String value, int scale) {
        BigDecimal bd = new BigDecimal(value);
        return bd.setScale(scale, 4).doubleValue();
    }

    public static double round(double value, int scale) {
        BigDecimal bd = new BigDecimal(value);
        return bd.setScale(scale, 4).doubleValue();
    }

下面咱們看看groovy中如何使用上面的class

Binding binding = new Binding();
        if(vars!=null) {
            vars.keySet().forEach(name ->
                    binding.setVariable(name, vars.get(name))
            );
        }
        CompilerConfiguration cfg = new CompilerConfiguration();
        cfg.setScriptBaseClass(EvalBaseScript.class.getName());
        GroovyShell shell = new GroovyShell(binding,cfg);

        try {
            Script script = shell.parse(buildScript());
            return script.run();
        } catch (Exception ex) {
            logger.error("catch script execution error, script:"+buildScript(), ex);
            return 0;
        }

至此java中執行自定義script的能力已經足夠了, 你能夠定義出你想要的, 任何腳本.

相關文章
相關標籤/搜索