如何计算字符串类型的数学表达式结果?代码示例求助
如何计算字符串类型的数学表达式值
你之前尝试用Double.parseDouble()失败,是因为这个方法只能解析纯数字格式的字符串,带+、*这类运算符的字符串不属于合法浮点数,会直接抛出NumberFormatException。
下面给你两种可行的实现方案:
方案一:使用Java自带的ScriptEngine(推荐)
Java内置了脚本引擎,可以直接执行字符串形式的表达式,支持运算符优先级、括号等常见语法,无需额外依赖:
import javax.script.ScriptEngineManager; import javax.script.ScriptEngine; import javax.script.ScriptException; // 嵌入到你的代码逻辑中 String x = dis.getText(); // 示例值:"2+3*4" ScriptEngineManager manager = new ScriptEngineManager(); // 调用JavaScript引擎计算表达式 ScriptEngine engine = manager.getEngineByName("JavaScript"); try { // 执行表达式并获取结果 Object result = engine.eval(x); dis.setText("Result :" + result); // 输出:Result :14 } catch (ScriptException e) { // 处理表达式不合法的情况 dis.setText("无效的表达式"); e.printStackTrace(); }
这个方案的优势:
- 无需自己处理运算符优先级、语法解析等复杂逻辑
- 支持绝大多数常见数学运算(加减乘除、取模、幂运算、括号嵌套等)
注意:如果应用会接收不可控的用户输入,要警惕脚本注入风险(比如输入恶意JavaScript代码),这种场景建议用方案二。
方案二:手动实现表达式解析(适合学习或定制需求)
如果不想依赖脚本引擎,可以自己实现简单的表达式计算器,核心思路是通过栈结构处理运算符优先级:
- 将中缀表达式(如
2+3*4)转换为后缀表达式(逆波兰表达式:2 3 4 * +) - 遍历后缀表达式,用栈计算最终结果
示例简化版代码(仅支持加减乘除):
import java.util.Stack; public class ExpressionCalculator { public static double calculate(String expr) throws Exception { Stack<Double> numStack = new Stack<>(); Stack<Character> opStack = new Stack<>(); int i = 0; while (i < expr.length()) { char c = expr.charAt(i); if (Character.isDigit(c) || c == '.') { // 解析数字(支持小数) StringBuilder sb = new StringBuilder(); while (i < expr.length() && (Character.isDigit(expr.charAt(i)) || expr.charAt(i) == '.')) { sb.append(expr.charAt(i++)); } numStack.push(Double.parseDouble(sb.toString())); } else if (isOperator(c)) { // 处理运算符优先级,栈顶优先级高则先计算 while (!opStack.isEmpty() && getPriority(opStack.peek()) >= getPriority(c)) { numStack.push(compute(numStack.pop(), numStack.pop(), opStack.pop())); } opStack.push(c); i++; } else { throw new Exception("无效字符:" + c); } } // 处理剩余运算符 while (!opStack.isEmpty()) { numStack.push(compute(numStack.pop(), numStack.pop(), opStack.pop())); } return numStack.pop(); } private static boolean isOperator(char c) { return c == '+' || c == '-' || c == '*' || c == '/'; } private static int getPriority(char op) { return op == '*' || op == '/' ? 2 : 1; } private static double compute(double b, double a, char op) { switch (op) { case '+': return a + b; case '-': return a - b; case '*': return a * b; case '/': if (b == 0) throw new ArithmeticException("除数不能为0"); return a / b; default: throw new IllegalArgumentException("未知运算符:" + op); } } }
使用方式:
String x = dis.getText(); try { double result = ExpressionCalculator.calculate(x); dis.setText("Result :" + result); } catch (Exception e) { dis.setText("计算出错:" + e.getMessage()); e.printStackTrace(); }
这个方案适合需要高度定制运算规则的场景,但需要自己处理更多边界情况(比如括号、负数、运算符优先级扩展等)。
内容的提问来源于stack exchange,提问作者LeviantArt
相关产品推荐
相关产品推荐

