JDK 1.5 (及所有標準版) 無內置 API 直接計算 "3*5+5" 這類字符串表達式。需自行實現或引入第三方庫。
* / > + -,左結合。import java.util.*;
public class ExprEval {
public static double eval(String expr) {
List postfix = toPostfix(tokenize(expr));
return calcPostfix(postfix);
}
static List tokenize(String s) {
List tokens = new ArrayList<>();
StringBuilder num = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (Character.isDigit(c) || c == '.') num.append(c);
else {
if (num.length() > 0) { tokens.add(num.toString()); num.setLength(0); }
if (c != ' ') tokens.add(String.valueOf(c));
}
}
if (num.length() > 0) tokens.add(num.toString());
return tokens;
}
static List toPostfix(List tokens) {
List out = new ArrayList<>();
Deque op = new ArrayDeque<>();
for (String t : tokens) {
if (isNumber(t)) out.add(t);
else if (t.equals("(")) op.push(t);
else if (t.equals(")")) {
while (!op.peek().equals("(")) out.add(op.pop());
op.pop();
} else { // operator
while (!op.isEmpty() && !op.peek().equals("(") && prec(op.peek()) >= prec(t))
out.add(op.pop());
op.push(t);
}
}
while (!op.isEmpty()) out.add(op.pop());
return out;
}
static int prec(String op) {
return (op.equals("*") || op.equals("/")) ? 2 : 1;
}
static boolean isNumber(String s) {
try { Double.parseDouble(s); return true; } catch { return false; }
}
static double calcPostfix(List postfix) {
Deque st = new ArrayDeque<>();
for (String t : postfix) {
if (isNumber(t)) st.push(Double.parseDouble(t));
else {
double b = st.pop(), a = st.pop();
switch (t) {
case "+": st.push(a + b); break;
case "-": st.push(a - b); break;
case "*": st.push(a * b); break;
case "/": st.push(a / b); break;
}
}
}
return st.pop();
}
public static void main(String[] args) {
System.out.println(eval("3*5+5")); // 20.0
}
}
new ExpressionBuilder("3*5+5").build().evaluate(),輕量、快、支援變量/函數。<dependency>
<groupId>net.objecthunter</groupId>
<artifactId>exp4j</artifactId>
<version>0.4.8</version>
</dependency>
不要重複造輪子,生產環境直接用 exp4j 等成熟庫;教學/面試可手寫 Shunting-yard 算法展示功力。