如何在类中用对象表示数学运算符以优化Java代码
嘿,你之前用switch处理不同运算符的写法确实够冗余的,想要用变量替代固定运算符实现通用二元运算的思路太对了!我给你两种靠谱的解决方案,一种是更符合Java最佳实践的轻量实现,另一种是搞定你用ScriptEngine时遇到的变量运算符问题~
通用二元运算实现方案
方案一:Map+Lambda轻量实现(推荐,无脚本引擎开销)
这种方式完全不需要依赖ScriptEngine,直接把运算符和对应的运算逻辑绑定,既简洁又高效,还能轻松扩展新运算符:
首先定义你的BinaryOperation函数式接口(如果还没定义的话):
@FunctionalInterface public interface BinaryOperation { double apply(double n1, double n2); }
然后用一个Map存储运算符到运算逻辑的映射,之后直接根据运算符获取对应逻辑执行:
import java.util.Map; import java.util.function.BinaryOperator; public class OperationHandler { // 预定义支持的运算符和对应的运算逻辑,想加新运算符直接在这里加就行 private static final Map<String, BinaryOperator<Double>> OP_MAP = Map.of( "+", (n1, n2) -> n1 + n2, "-", (n1, n2) -> n1 - n2, "*", (n1, n2) -> n1 * n2, "/", (n1, n2) -> { if (n2 == 0) throw new ArithmeticException("除数不能为0"); return n1 / n2; }, "%", (n1, n2) -> n1 % n2 ); // 根据运算符获取对应的BinaryOperation实例 public static BinaryOperation getOperation(String operator) { BinaryOperator<Double> op = OP_MAP.get(operator); if (op == null) { throw new IllegalArgumentException("不支持的运算符: " + operator); } return op::apply; } // 直接执行运算的工具方法,一步到位 public static double calculate(double n1, double n2, String operator) { return getOperation(operator).apply(n1, n2); } }
使用的时候超简单,直接传入运算符即可:
public class Main { public static void main(String[] args) { double addResult = OperationHandler.calculate(15, 7, "+"); double divideResult = OperationHandler.calculate(15, 3, "/"); System.out.println(addResult); // 输出22.0 System.out.println(divideResult); // 输出5.0 } }
这种方式完美符合开闭原则,新增运算符不需要修改原有逻辑,只需要在Map里加一行配置就行,比switch清爽太多。
方案二:解决ScriptEngine的变量运算符问题
如果你坚持想用ScriptEngine的话,问题出在你把OP定义成了固定常量,没办法传入运算符变量。我们可以把它改成一个接收运算符参数的方法:
import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; @FunctionalInterface public interface BinaryOperation { double apply(double n1, double n2); } public class ScriptOperation { public static BinaryOperation getScriptOperation(String operator) { return (n1, n2) -> { ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); try { // 直接把运算符变量拼进表达式字符串里即可 return (double) engine.eval(n1 + " " + operator + " " + n2); } catch (ScriptException e) { throw new RuntimeException("运算执行出错: " + e.getMessage(), e); } }; } public static void main(String[] args) { BinaryOperation multiplyOp = getScriptOperation("*"); System.out.println(multiplyOp.apply(9, 4)); // 输出36.0 BinaryOperation subtractOp = getScriptOperation("-"); System.out.println(subtractOp.apply(9, 4)); // 输出5.0 } }
不过要提醒你,ScriptEngine方式有几个明显缺点:性能比原生Lambda差很多、存在脚本注入的安全风险(如果运算符来自用户输入)、异常处理不如原生Java灵活,所以还是更推荐第一种方案。
内容的提问来源于stack exchange,提问作者Elias
相关产品推荐
相关产品推荐

