Java中是否有eval()函数?

时间:2010-04-09 04:07:52

标签: java eval

我有一个如下字符串:

String str = "4*5";

现在我必须使用字符串来获取20的结果。

我知道在其他一些语言中,eval()函数会执行此操作。 我怎么能用Java做到这一点?

14 个答案:

答案 0 :(得分:136)

您可以使用ScriptEngine类并将其评估为Javascript字符串。

ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
Object result = engine.eval("4*5");

可能有更好的方法,但这个方法有效。

答案 1 :(得分:43)

没有标准的Java类或方法可以执行您想要的操作。您的选择包括:

  • 选择并使用某些第三方表达式评估库。例如JEL或列出的半打图书库here中的任何一个。

  • 使用eval方法将表达式包装在Java源代码中,将其发送到Java编译器,然后加载生成的编译类。

  • 使用一些可以从Java调用的脚本语言作为表达式求值程序。可能性包括Javascript,BeanShell等。

  • 从头开始编写自己的表达式评估程序。

第一种方法可能最简单。如果从不受信任的用户获得要评估的表达式,则第二种和第三种方法存在潜在的安全风险。 (想想代码注入。)

答案 2 :(得分:30)

很少有真正的用例能够将String评估为Java代码片段是必要或可取的。也就是说,询问如何做到这一点真的是XY problem:你实际上有一个不同的问题,可以用不同的方式解决。

首先问问自己,您希望评估的String来自何处?您的程序的另一部分是否生成了它,或者是由用户提供的输入?

  • 我的程序的另一部分生成了它:所以,你希望程序的一部分决定要执行的操作类型,但不执行操作,第二部分是执行所选操作。不要生成然后评估String,而是根据您的具体情况使用StrategyCommandBuilder设计模式。

  • 用户输入:用户可以输入任何,包括执行时可能导致程序出现异常,崩溃,泄露信息的命令应该是秘密的,破坏持久性信息(例如数据库的内容),以及其他这样的肮脏。防止这种情况的唯一方法是自己解析String,检查它是否是恶意的,然后对其进行评估。但是自己解析它是所请求的eval函数所做的大部分工作,所以你没有为自己节省任何东西。更糟糕的是,检查任意Java是不是恶意的不可能,因为检查是halting problem

  • 这是用户输入,但是要评估的允许文本的语法和语义受到很大限制:没有通用工具可以轻松地实现通用解析器和评估器,无论是什么限制语法和你选择的语义。您需要做的是为您选择的语法和语义实现解析器和求值程序。如果任务很简单,您可以手动编写一个简单的recursive-descent或有限状态机解析器。如果任务很困难,您可以使用compiler-compiler(例如ANTLR)为您完成一些工作。

  • 我只是想实现一个桌面计算器!:做作业,呃?如果你可以使用提供的eval函数来实现输入表达式的评估,那么这不是一个很好的家庭作业,是吗?你的程序将长三行。您的教师可能希望您为简单的算术解析器/评估器编写代码。众所周知的算法shunting-yard,您可能会发现它很有用。

答案 3 :(得分:11)

我可以建议你使用Exp4j。从以下示例代码中可以看出,这很容易理解:

Expression e = new ExpressionBuilder("3 * sin(y) - 2 / (x - 2)")
    .variables("x", "y")
    .build()
    .setVariable("x", 2.3)
    .setVariable("y", 3.14);
double result = e.evaluate();

答案 4 :(得分:7)

使用Java 9,我们可以访问jshell,因此可以编写如下内容:

import jdk.jshell.JShell;
import java.lang.StringBuilder;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Eval {
    public static void main(String[] args) throws IOException {
        try(JShell js = JShell.create(); BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {

            js.onSnippetEvent(snip -> {
                if (snip.status() == jdk.jshell.Snippet.Status.VALID) {
                    System.out.println("➜ " + snip.value());
                }
            });

            System.out.print("> ");
            for (String line = br.readLine(); line != null; line = br.readLine()) {
                js.eval(js.sourceCodeAnalysis().analyzeCompletion(line).source());
                System.out.print("> ");
            }
        }
    }
}

样品运行:

> 1 + 2 / 4 * 3
➜ 1
> 32 * 121
➜ 3872
> 4 * 5
➜ 20
> 121 * 51
➜ 6171
>

稍微OP,但这就是Java当前所提供的

答案 5 :(得分:6)

如前所述,Java中没有标准的API。

您可以将groovy jar文件添加到路径中,并且groovy.util.Eval.me(“4 * 5”)可以完成您的工作。

答案 6 :(得分:5)

,您不能在Java(或任何编译语言)中使用通用的“eval”。除非您愿意编写Java编译器和JVM以在Java程序中执行

,您可以使用一些库来评估上面的数字代数表达式 - see this thread for discussion

答案 7 :(得分:4)

解决问题的有趣方法可能是自己编写eval()函数! 我已经为你做了!

只需在代码中输入 FunctionSolver.solveByX( function value ,即可使用FunctionSolver库。 function 属性是一个表示要解决的函数的String, value 属性是自变量的值  你的功能(必须是x)。

如果要解决包含多个自变量的函数,可以使用 FunctionSolver.solve(函数其中 values 属性是HashMap(String,Double),其中包含所有独立属性(如字符串)及其各自的值(作为双打)。

另一条信息:我编写了一个简单版本的 FunctionSolver ,因此它只支持Math methods,它返回一个double值,并接受一个或两个double值作为字段(如果你很好奇,只需使用 FunctionSolver.usableMathMethods()(这些方法是: bs,sin,cos,tan,atan2,sqrt,log,log10,pow,exp,min, max,copySign,signum,IEEEremainder,acos,asin,atan,cbrt,ceil,cosh,expm1,floor,hypot,log1p,nextAfter,nextDown,nextUp,random,rint,sinh,tanh,toDegrees,toRadians,ulp)。此外,该库支持以下运算符:* / + - ^(即使java通常不支持^运算符)。

最后一件事:创建此库时,我必须使用reflections来调用Math methods。如果您对此感兴趣,我认为它真的很酷,只有have a look at this

就是这样,这里是代码(和library):

package core;

 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;

 public abstract class FunctionSolver {

public static double solveNumericExpression (String expression) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    return solve(expression, new HashMap<>());
}

public static double solveByX (String function, double value) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

    HashMap<String, Double> values = new HashMap<>();
    values.put("x", value);
    return solveComplexFunction(function, function, values);
}

public static double solve (String function, HashMap<String,Double> values) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

    return solveComplexFunction(function, function, values);
}

private static double solveComplexFunction (String function, String motherFunction, HashMap<String, Double> values) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

    int position = 0;
    while(position < function.length()) {
        if (alphabetic.contains(""+function.charAt(position))) {
            if (position == 0 || !alphabetic.contains(""+function.charAt(position-1))) {
                int endIndex = -1;
                for (int j = position ; j < function.length()-1 ; j++) {
                    if (alphabetic.contains(""+function.charAt(j)) 
                            && !alphabetic.contains(""+function.charAt(j+1))) {
                        endIndex = j;
                        break;
                    }
                }
                if (endIndex == -1 & alphabetic.contains(""+function.charAt(function.length()-1))) {
                    endIndex = function.length()-1;
                }
                if (endIndex != -1) {
                    String alphabeticElement = function.substring(position, endIndex+1);
                    if (Arrays.asList(usableMathMethods()).contains(alphabeticElement)) {
                        //Start analyzing a Math function
                        int closeParenthesisIndex = -1;
                        int openedParenthesisquantity = 0;
                        int commaIndex = -1;
                        for (int j = endIndex+1 ; j < function.length() ; j++) {
                            if (function.substring(j,j+1).equals("(")) {
                                openedParenthesisquantity++;
                            }else if (function.substring(j,j+1).equals(")")) {
                                openedParenthesisquantity--;
                                if (openedParenthesisquantity == 0) {
                                    closeParenthesisIndex = j;
                                    break;
                                }
                            }else if (function.substring(j,j+1).equals(",") & openedParenthesisquantity == 0) {
                                if (commaIndex == -1) {
                                    commaIndex = j;
                                }else{
                                    throw new IllegalArgumentException("The argument of math function (which is "+alphabeticElement+") has too many commas");
                                }
                            }
                        }
                        if (closeParenthesisIndex == -1) {
                            throw new IllegalArgumentException("The argument of a Math function (which is "+alphabeticElement+") hasn't got the closing bracket )");
                        }   
                        String functionArgument = function.substring(endIndex+2,closeParenthesisIndex);
                        if (commaIndex != -1) {
                            double firstParameter = solveComplexFunction(functionArgument.substring(0,commaIndex),motherFunction,values);
                            double secondParameter = solveComplexFunction(functionArgument.substring(commaIndex+1),motherFunction,values);
                            Method mathMethod = Math.class.getDeclaredMethod(alphabeticElement, new Class<?>[] {double.class, double.class});
                            mathMethod.setAccessible(true);
                            String newKey = getNewKey(values);
                            values.put(newKey, (Double) mathMethod.invoke(null, firstParameter, secondParameter));
                            function = function.substring(0, position)+newKey
                                       +((closeParenthesisIndex == function.length()-1)?(""):(function.substring(closeParenthesisIndex+1)));
                        }else {
                            double firstParameter = solveComplexFunction(functionArgument, motherFunction, values);
                            Method mathMethod = Math.class.getDeclaredMethod(alphabeticElement, new Class<?>[] {double.class});
                            mathMethod.setAccessible(true);
                            String newKey = getNewKey(values);
                            values.put(newKey, (Double) mathMethod.invoke(null, firstParameter));
                            function = function.substring(0, position)+newKey
                                       +((closeParenthesisIndex == function.length()-1)?(""):(function.substring(closeParenthesisIndex+1)));
                        }   
                    }else if (!values.containsKey(alphabeticElement)) {
                        throw new IllegalArgumentException("Found a group of letters ("+alphabeticElement+") which is neither a variable nor a Math function: ");
                    }
                }
            }
        }
        position++;
    }
    return solveBracketsFunction(function,motherFunction,values);
}

private static double solveBracketsFunction (String function,String motherFunction,HashMap<String, Double> values) throws IllegalArgumentException{

    function = function.replace(" ", "");
    String openingBrackets = "([{";
    String closingBrackets = ")]}";
    int parenthesisIndex = 0;
    do {
        int position = 0;
        int openParenthesisBlockIndex = -1;
        String currentOpeningBracket = openingBrackets.charAt(parenthesisIndex)+"";
        String currentClosingBracket = closingBrackets.charAt(parenthesisIndex)+"";
        if (contOccouranceIn(currentOpeningBracket,function) != contOccouranceIn(currentClosingBracket,function)) {
            throw new IllegalArgumentException("Error: brackets are misused in the function "+function);
        }
        while (position < function.length()) {
            if (function.substring(position,position+1).equals(currentOpeningBracket)) {
                if (position != 0 && !operators.contains(function.substring(position-1,position))) {
                    throw new IllegalArgumentException("Error in function: there must be an operator following a "+currentClosingBracket+" breacket");
                }
                openParenthesisBlockIndex = position;
            }else if (function.substring(position,position+1).equals(currentClosingBracket)) {
                if (position != function.length()-1 && !operators.contains(function.substring(position+1,position+2))) {
                    throw new IllegalArgumentException("Error in function: there must be an operator before a "+currentClosingBracket+" breacket");
                }
                String newKey = getNewKey(values);
                values.put(newKey, solveBracketsFunction(function.substring(openParenthesisBlockIndex+1,position),motherFunction, values));
                function = function.substring(0,openParenthesisBlockIndex)+newKey
                           +((position == function.length()-1)?(""):(function.substring(position+1)));
                position = -1;
            }
            position++;
        }
        parenthesisIndex++;
    }while (parenthesisIndex < openingBrackets.length());
    return solveBasicFunction(function,motherFunction, values);
}

private static double solveBasicFunction (String function, String motherFunction, HashMap<String, Double> values) throws IllegalArgumentException{

    if (!firstContainsOnlySecond(function, alphanumeric+operators)) {
        throw new IllegalArgumentException("The function "+function+" is not a basic function");
    }
    if (function.contains("**") |
        function.contains("//") |
        function.contains("--") |
        function.contains("+*") |
        function.contains("+/") |
        function.contains("-*") |
        function.contains("-/")) {
        /*
         * ( -+ , +- , *- , *+ , /- , /+ )> Those values are admitted
         */
        throw new IllegalArgumentException("Operators are misused in the function");
    }
    function = function.replace(" ", "");
    int position;
    int operatorIndex = 0;
    String currentOperator;
    do {
        currentOperator = operators.substring(operatorIndex,operatorIndex+1);
        if (currentOperator.equals("*")) {
            currentOperator+="/";
            operatorIndex++;
        }else if (currentOperator.equals("+")) {
            currentOperator+="-";
            operatorIndex++;
        }
        operatorIndex++;
        position = 0;
        while (position < function.length()) {
            if ((position == 0 && !(""+function.charAt(position)).equals("-") && !(""+function.charAt(position)).equals("+") && operators.contains(""+function.charAt(position))) ||
                (position == function.length()-1 && operators.contains(""+function.charAt(position)))){
                throw new IllegalArgumentException("Operators are misused in the function");
            }
            if (currentOperator.contains(function.substring(position, position+1)) & position != 0) {
                int firstTermBeginIndex = position;
                while (firstTermBeginIndex > 0) {
                    if ((alphanumeric.contains(""+function.charAt(firstTermBeginIndex))) & (operators.contains(""+function.charAt(firstTermBeginIndex-1)))){
                        break;
                    }
                    firstTermBeginIndex--;
                }
                if (firstTermBeginIndex != 0 && (function.charAt(firstTermBeginIndex-1) == '-' | function.charAt(firstTermBeginIndex-1) == '+')) {
                    if (firstTermBeginIndex == 1) {
                        firstTermBeginIndex--;
                    }else if (operators.contains(""+(function.charAt(firstTermBeginIndex-2)))){
                        firstTermBeginIndex--;
                    }
                }
                String firstTerm = function.substring(firstTermBeginIndex,position);
                int secondTermLastIndex = position;
                while (secondTermLastIndex < function.length()-1) {
                    if ((alphanumeric.contains(""+function.charAt(secondTermLastIndex))) & (operators.contains(""+function.charAt(secondTermLastIndex+1)))) {
                        break;
                    }
                    secondTermLastIndex++;
                }
                String secondTerm = function.substring(position+1,secondTermLastIndex+1);
                double result;
                switch (function.substring(position,position+1)) {
                    case "*": result = solveSingleValue(firstTerm,values)*solveSingleValue(secondTerm,values); break;
                    case "/": result = solveSingleValue(firstTerm,values)/solveSingleValue(secondTerm,values); break;
                    case "+": result = solveSingleValue(firstTerm,values)+solveSingleValue(secondTerm,values); break;
                    case "-": result = solveSingleValue(firstTerm,values)-solveSingleValue(secondTerm,values); break;
                    case "^": result = Math.pow(solveSingleValue(firstTerm,values),solveSingleValue(secondTerm,values)); break;
                    default: throw new IllegalArgumentException("Unknown operator: "+currentOperator);
                }
                String newAttribute = getNewKey(values);
                values.put(newAttribute, result);
                function = function.substring(0,firstTermBeginIndex)+newAttribute+function.substring(secondTermLastIndex+1,function.length());
                deleteValueIfPossible(firstTerm, values, motherFunction);
                deleteValueIfPossible(secondTerm, values, motherFunction);
                position = -1;
            }
            position++;
        }
    }while (operatorIndex < operators.length());
    return solveSingleValue(function, values);
}

private static double solveSingleValue (String singleValue, HashMap<String, Double> values) throws IllegalArgumentException{

    if (isDouble(singleValue)) {
        return Double.parseDouble(singleValue);
    }else if (firstContainsOnlySecond(singleValue, alphabetic)){
        return getValueFromVariable(singleValue, values);
    }else if (firstContainsOnlySecond(singleValue, alphanumeric+"-+")) {
        String[] composition = splitByLettersAndNumbers(singleValue);
        if (composition.length != 2) {
            throw new IllegalArgumentException("Wrong expression: "+singleValue);
        }else {
            if (composition[0].equals("-")) {
                composition[0] = "-1";
            }else if (composition[1].equals("-")) {
                composition[1] = "-1";
            }else if (composition[0].equals("+")) {
                composition[0] = "+1";
            }else if (composition[1].equals("+")) {
                composition[1] = "+1";
            }
            if (isDouble(composition[0])) {
                return Double.parseDouble(composition[0])*getValueFromVariable(composition[1], values);
            }else if (isDouble(composition[1])){
                return Double.parseDouble(composition[1])*getValueFromVariable(composition[0], values);
            }else {
                throw new IllegalArgumentException("Wrong expression: "+singleValue);
            }
        }
    }else {
        throw new IllegalArgumentException("Wrong expression: "+singleValue);
    }
}

private static double getValueFromVariable (String variable, HashMap<String, Double> values) throws IllegalArgumentException{

    Double val = values.get(variable);
    if (val == null) {
        throw new IllegalArgumentException("Unknown variable: "+variable);
    }else {
        return val;
    }
}

/*
 * FunctionSolver help tools:
 * 
 */

private static final String alphabetic = "abcdefghilmnopqrstuvzwykxy";
private static final String numeric = "0123456789.";
private static final String alphanumeric = alphabetic+numeric;
private static final String operators = "^*/+-"; //--> Operators order in important!

private static boolean firstContainsOnlySecond(String firstString, String secondString) {

    for (int j = 0 ; j < firstString.length() ; j++) {
        if (!secondString.contains(firstString.substring(j, j+1))) {
            return false;
        }
    }
    return true;
}

private static String getNewKey (HashMap<String, Double> hashMap) {

    String alpha = "abcdefghilmnopqrstuvzyjkx";
    for (int j = 0 ; j < alpha.length() ; j++) {
        String k = alpha.substring(j,j+1);
        if (!hashMap.containsKey(k) & !Arrays.asList(usableMathMethods()).contains(k)) {
            return k;
        }
    }
    for (int j = 0 ; j < alpha.length() ; j++) {
        for (int i = 0 ; i < alpha.length() ; i++) {
            String k = alpha.substring(j,j+1)+alpha.substring(i,i+1);
            if (!hashMap.containsKey(k) & !Arrays.asList(usableMathMethods()).contains(k)) {
                return k;
            }
        }
    }
    throw new NullPointerException();
}

public static String[] usableMathMethods () {

    /*
     *  Only methods that:
     *  return a double type
     *  present one or two parameters (which are double type)
     */

    Method[] mathMethods = Math.class.getDeclaredMethods();
    ArrayList<String> usableMethodsNames = new ArrayList<>();
    for (Method method : mathMethods) {
        boolean usable = true;
        int argumentsCounter = 0;
        Class<?>[] methodParametersTypes = method.getParameterTypes();
        for (Class<?> parameter : methodParametersTypes) {
            if (!parameter.getSimpleName().equalsIgnoreCase("double")) {
                usable = false;
                break;
            }else {
                argumentsCounter++;
            }
        }
        if (!method.getReturnType().getSimpleName().toLowerCase().equals("double")) {
            usable = false;
        }
        if (usable & argumentsCounter<=2) {
            usableMethodsNames.add(method.getName());
        }
    }
    return usableMethodsNames.toArray(new String[usableMethodsNames.size()]);
}

private static boolean isDouble (String number) {
    try {
        Double.parseDouble(number);
        return true;
    }catch (Exception ex) {
        return false;
    }
}

private static String[] splitByLettersAndNumbers (String val) {
    if (!firstContainsOnlySecond(val, alphanumeric+"+-")) {
        throw new IllegalArgumentException("Wrong passed value: <<"+val+">>");
    }
    ArrayList<String> response = new ArrayList<>();
    String searchingFor;
    int lastIndex = 0;
    if (firstContainsOnlySecond(""+val.charAt(0), numeric+"+-")) {
        searchingFor = alphabetic;
    }else {
        searchingFor = numeric+"+-";
    }
    for (int j = 0 ; j < val.length() ; j++) {
        if (searchingFor.contains(val.charAt(j)+"")) {
            response.add(val.substring(lastIndex, j));
            lastIndex = j;
            if (searchingFor.equals(numeric+"+-")) {
                searchingFor = alphabetic;
            }else {
                searchingFor = numeric+"+-";
            }
        }
    }
    response.add(val.substring(lastIndex,val.length()));
    return response.toArray(new String[response.size()]);
}

private static void deleteValueIfPossible (String val, HashMap<String, Double> values, String function) {
    if (values.get(val) != null & function != null) {
        if (!function.contains(val)) {
            values.remove(val);
        }
    }
}

private static int contOccouranceIn (String howManyOfThatString, String inThatString) {
    return inThatString.length() - inThatString.replace(howManyOfThatString, "").length();
}
 }

答案 8 :(得分:3)

编写自己的库并不像你想象的那么难。这是Shunting-yard algorithm与逐步算法explenation的链接。虽然,您必须首先解析令牌的输入。

还有其他两个问题可以为您提供一些信息: Turn a String into a Math Expression? What's a good library for parsing mathematical expressions in java?

答案 9 :(得分:1)

有很多答案,我将在eval()方法的顶部添加实现,并添加一些其他功能,例如支持阶乘,评估复杂表达式等。

package evaluation;

import java.math.BigInteger;
import java.util.EmptyStackException;
import java.util.Scanner;
import java.util.Stack;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class EvalPlus {
    private static Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) {
        System.out.println("This Evaluation is based on BODMAS rule\n");
        evaluate();
    }

    private static void evaluate() {
        StringBuilder finalStr = new StringBuilder();
        System.out.println("Enter an expression to evaluate:");
        String expr = scanner.nextLine(); 
        if(isProperExpression(expr)) {
            expr = replaceBefore(expr);
            char[] temp = expr.toCharArray();
            String operators = "(+-*/%)";
            for(int i = 0; i < temp.length; i++) {
                if((i == 0 && temp[i] != '*') || (i == temp.length-1 && temp[i] != '*' && temp[i] != '!')) {
                    finalStr.append(temp[i]);
                } else if((i > 0 && i < temp.length -1) || (i==temp.length-1 && temp[i] == '!')) {
                    if(temp[i] == '!') {
                        StringBuilder str = new StringBuilder();
                        for(int k = i-1; k >= 0; k--) {
                            if(Character.isDigit(temp[k])) {
                                str.insert(0, temp[k] );
                            } else {
                                break;
                            }
                        }
                        Long prev = Long.valueOf(str.toString());
                        BigInteger val = new BigInteger("1");
                        for(Long j = prev; j > 1; j--) {
                            val = val.multiply(BigInteger.valueOf(j));
                        }
                        finalStr.setLength(finalStr.length() - str.length());
                        finalStr.append("(" + val + ")");
                        if(temp.length > i+1) {
                            char next = temp[i+1];
                            if(operators.indexOf(next) == -1) { 
                                finalStr.append("*");
                            }
                        }
                    } else {
                        finalStr.append(temp[i]);
                    }
                }
            }
            expr = finalStr.toString();
            if(expr != null && !expr.isEmpty()) {
                ScriptEngineManager mgr = new ScriptEngineManager();
                ScriptEngine engine = mgr.getEngineByName("JavaScript");
                try {
                    System.out.println("Result: " + engine.eval(expr));
                    evaluate();
                } catch (ScriptException e) {
                    System.out.println(e.getMessage());
                }
            } else {
                System.out.println("Please give an expression");
                evaluate();
            }
        } else {
            System.out.println("Not a valid expression");
            evaluate();
        }
    }

    private static String replaceBefore(String expr) {
        expr = expr.replace("(", "*(");
        expr = expr.replace("+*", "+").replace("-*", "-").replace("**", "*").replace("/*", "/").replace("%*", "%");
        return expr;
    }

    private static boolean isProperExpression(String expr) {
        expr = expr.replaceAll("[^()]", "");
        char[] arr = expr.toCharArray();
        Stack<Character> stack = new Stack<Character>();
        int i =0;
        while(i < arr.length) {
            try {
                if(arr[i] == '(') {
                    stack.push(arr[i]);
                } else {
                    stack.pop();
                }
            } catch (EmptyStackException e) {
                stack.push(arr[i]);
            }
            i++;
        }
        return stack.isEmpty();
    }
}

请随时here找到更新的要点。如果有任何问题,也请发表评论。谢谢。

答案 10 :(得分:0)

在JavaSE中没有任何东西可以做到这一点;你必须找到第三方图书馆或自己编写。

答案 11 :(得分:0)

这里有一些非常有能力的答案。但是,对于非平凡的脚本,可能需要将代码保留在缓存中,或者用于调试目的,甚至具有动态的自我更新代码。

为此,有时是simpler or more robust to interact with Java via command lineCreate a temporary directoryoutput your script和任何资产create the jar。最后import your new code

尽管您可以通过从jar中的某些函数返回结果来实现eval,但它在大多数语言中的常规eval()的使用范围也有所超出。

还是,我想提一提这种方法,因为它可以完全封装Java,而在万一无奈的情况下,无需第三方工具就可以做到。这种方法使我可以将HTML模板转换为对象并保存它们,而无需在运行时解析模板。

答案 12 :(得分:0)

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

class Calculate {
    public static void main(String[] args) {
        String  strng = "8*-2*3*-1*10/2+6-2";
        String[] oparator = {"+","-","*","/"};
        List<String> op1 = new ArrayList<>();
        String[] x = strng.split("");

        int sayac=0;
        for (String i : x) {
            sayac ++;
            for (String c : oparator) {
                if (i.equals(c)) {

                   try {
                       int j = Integer.parseInt(strng.substring(0, sayac - 1));
                       op1.add(strng.substring(0, sayac - 1));
                       op1.add(c);
                       strng = strng.substring(sayac);
                       sayac = 0;
                   }catch (Exception e)
                   {
                       continue;
                   }
                }

            }
        }
        op1.add(strng);

        ListIterator<String> it = op1.listIterator();
        List<List> newlist = new ArrayList<>() ;

        while (it.hasNext()) {

            List<String> p= new ArrayList<>();
            p.add(String.valueOf(it.nextIndex()));
            p.add(it.next());
            newlist.add(p);

        }

        int sayac2=0;
        String oparatorvalue = "*";
        calculate(sayac2,newlist,oparatorvalue);
        String oparatorvalue2 = "/";
        calculate(sayac2,newlist,oparatorvalue2);
        String oparatorvalue3 = "+";
        calculate(sayac2,newlist,oparatorvalue3);
        String oparatorvalue4 = "-";
        calculate(sayac2,newlist,oparatorvalue4);
        System.out.println("Result:"+newlist.get(0).get(1));


    }


    private static void calculate(int sayac2, List<List> newlist, String oparatorvalue) {
        while (sayac2<4){
            try{
                for (List j : newlist) {
                    if (j.get(1) == oparatorvalue) {
                        Integer opindex = newlist.indexOf(j);
                        Object sayi1 = newlist.get(opindex - 1).get(1);
                        Object sayi2 = newlist.get(opindex + 1).get(1);
                        int sonuc=0;
                        if (oparatorvalue.equals("*")){

                         sonuc = Integer.parseInt(sayi1.toString()) * Integer.parseInt(sayi2.toString());
                        }
                        if (oparatorvalue.equals("/")){

                            sonuc = Integer.parseInt(sayi1.toString()) / Integer.parseInt(sayi2.toString());
                        }
                        if (oparatorvalue.equals("+")){

                            sonuc = Integer.parseInt(sayi1.toString()) + Integer.parseInt(sayi2.toString());
                        }
                        if (oparatorvalue.equals("-")){

                            sonuc = Integer.parseInt(sayi1.toString()) - Integer.parseInt(sayi2.toString());
                        }
                        newlist.remove(opindex - 1);
                        newlist.remove(opindex - 1);
                        newlist.remove(opindex - 1);
                        List<String> sonuclist = new ArrayList<>();
                        sonuclist.add(String.valueOf(opindex - 1));
                        sonuclist.add(String.valueOf(sonuc));
                        newlist.add(opindex - 1, sonuclist);
                    }}}
            catch (Exception e){
                continue;
            }
            sayac2++;}
    }

}

答案 13 :(得分:-2)

以下内容解决了该问题:

ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
String str = "4*5";
System.out.println(engine.eval(str));