安卓(Android)或者Java使用rhino实现任意字符串表达式计算

安卓(Android)或者Java使用rhino实现任意字符串表达式计算

本文连接:https://www.cnblogs.com/muphy/p/15253488.html

Java使用rhino

引入依赖包

<!-- https://mvnrepository.com/artifact/org.mozilla/rhino -->
<dependency>
    <groupId>org.mozilla</groupId>
    <artifactId>rhino</artifactId>
    <version>1.7.13</version>
</dependency>

初始rhino的Context

Context.enter();

安卓系统使用rhino不太一样,安卓使用参考:https://github.com/F43nd1r/rhino-android

引入依赖包

implementation 'com.faendir.rhino:rhino-android:1.6.0'
//implementation group: 'org.mozilla', name: 'rhino', version: '1.7.13'

初始化rhino的Context

//这里参数context使用Android的Context
new RhinoAndroidHelper(context).enterContext()

AndroidContextHolder.java

import android.content.Context;

public class AndroidContextHolder {
    private static Context context;

    public static Context getContext() {
        return context;
    }

    public static void setContext(Context context) {
        AndroidContextHolder.context = context;
    }
}

CalculateUtils.java

//package com.moefon.power.spring.util;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.Undefined;

import java.util.Stack;

/**
 * 将字符串转计算公式
 * Object r1 = evaluate("function f(){var x = 5; y = 455; var m = {'x':x,'y':y}; return x}; var i = f();"); // Undefined
 * Object r2 = evaluate("function f(){var x = 5; y = 455; var m = {'x':x,'y':y}; return x}; var i = f(); i;"); // Integer:5
 * Object r3 = evaluate("var f = function(){var x = 5; var m = {'x':x,'y':55}; return m}; var i = f();", "i"); // NativeObject:{'x':x,'y':y}
 * Object r4 = evaluate("var f = function(v){var x = 5; var m = {'x':x,'y':v}; return m;};", "f", 1); // NativeObject:{'x':x,'y':y}
 * Object r5 = evaluate("var f = function(v){var x = 5; var m = {'x':x,'y':v}; return x + v;};", "f", 1); // Double:5
 * 
 * AndroidContextHolder.getContext() 表示安卓启动的时候记得设置activity或者application
 *
 * @author: 若非
 * @date: 2021/9/9 20:43
 */
public class CalculateUtils {

    /**
     * 将字符串转计算公式 {@code evaluate(7+ +55 + +5 * (2-5)) }
     *
     * @param js
     * @return: 计算结果
     * @author: 若非
     * @date: 2021/9/9 20:43
     */
    public static <T> T evaluate(String js) {
        Context ctx = new RhinoAndroidHelper(AndroidContextHolder.getContext).enterContext();
        Scriptable scope = ctx.initStandardObjects();    //初始化本地对象
        T result = null;
        try {
            Object o = ctx.evaluateString(scope, js, "", 1, null);
            if (o != Scriptable.NOT_FOUND && !(o instanceof Undefined)) {
                result = (T) o;//执行
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 执行JS代码
     *
     * @param js
     * @param resultName scope中获取返回参数名称
     * @return: js对象 计算结果
     * @author: 若非
     * @date: 2021/9/9 20:43
     */
    public static <T> T evaluate(String js, String resultName) {
        Context ctx = new RhinoAndroidHelper(AndroidContextHolder.getContext()).enterContext();
        Scriptable scope = ctx.initStandardObjects();    //初始化本地对象
        T result = null;
        try {
            ctx.evaluateString(scope, js, "", 1, null);//执行
        } catch (Exception e) {
            e.printStackTrace();
        }
        Object o = scope.get(resultName, scope);
        if (o != Scriptable.NOT_FOUND && !(o instanceof Undefined)) {
            result = (T) o;//执行
        }
        return result;
    }

    /**
     * 执行JS代码
     *
     * @param js             js代码
     * @param functionName   js方法名称
     * @param functionParams js方法参数
     * @return js对象
     * @author: 若非
     * @date: 2021/9/9 20:43
     */
    public static <T> T evaluate(String js, String functionName, Object... functionParams) {
        Context ctx = new RhinoAndroidHelper(AndroidContextHolder.getContext()).enterContext();
        ctx.setOptimizationLevel(-1);
        T result = null;
        try {
            Scriptable scope = ctx.initStandardObjects();
            ctx.evaluateString(scope, js, null, 1, null);
            Function function = (Function) scope.get(functionName, scope);
            Object o = function.call(ctx, scope, scope, functionParams);
            if (o != Scriptable.NOT_FOUND && !(o instanceof Undefined)) {
                result = (T) o;//执行
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 加减乘除计算 使用包装类方便取值
     *
     * @param expression
     * @return
     * @author: 若非
     * @date: 2021/9/9 20:43
     * @see this#evaluate
     * @deprecated {@code this.evaluate}
     */
    @Remind(deprecated = true, notice = "请使用evaluate方法来进行表达式计算,这里只支持+-*/")
    public static Double calculationResult(String expression) {
        char[] chars = expression.toCharArray();
        Stack<String> stack = new Stack<>();
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < chars.length; i++) {
            switch (chars[i]) {
                case '+':
                case '-':
                    stack.push(stringBuilder.toString());
                    stack.push(String.valueOf(calculationResult(stack)));
                    stack.push(chars[i] + "");
                    stringBuilder = new StringBuilder();
                    break;
                case '*':
                case '/':
                    stack.push(stringBuilder.toString());
                    stack.push(chars[i] + "");
                    stringBuilder = new StringBuilder();
                    break;
                default:
                    stringBuilder.append(chars[i]);
            }
        }
        stack.push(stringBuilder.toString());
        Double v = calculationResult(stack);
        return v;
    }

    /**
     * 加减乘除计算 使用包装类方便取值
     *
     * @param stack
     * @return 执行结果
     * @author: 若非
     * @date: 2021/9/9 20:43
     * @see this#evaluate
     * @deprecated {@code this.evaluate}
     */
    private static Double calculationResult(Stack<String> stack) {
        double res = Double.parseDouble(stack.pop());
        while (!stack.empty()) {
            String opt = stack.pop();
            double second = Double.parseDouble(stack.pop());
            res = calculation(res, second, opt.charAt(0));
        }
        return res;
    }

    /**
     * 加减乘除计算 使用包装类方便取值
     *
     * @param res
     * @param x
     * @param opt
     * @return 执行结果
     * @author: 若非
     * @date: 2021/9/9 20:43
     * @see this#evaluate
     * @deprecated {@code this.evaluate}
     */
    private static Double calculation(double res, double x, char opt) {
        switch (opt) {
            case '+':
                return res + x;
            case '-':
                return x - res;
            case '*':
                return res * x;
            case '/':
                if (x < 0.0000000001f) {
                    return Double.MAX_VALUE;
                }
                return x / res;
            default:
                return res;
        }
    }
}

 

posted @ 2021-09-11 00:04  明月心~  阅读(435)  评论(0编辑  收藏  举报