Java如何将单/双字符运算符转为可执行运算符?无依赖实现
Java中优化char[]运算符转可执行逻辑的方案
需求与问题
需要将char[]类型的单字符(如+、-、<)或双字符(如>=、<=、==)运算符转为可执行运算,现有实现存在大量重复的类型判断和分支逻辑,希望优化,且不依赖任何第三方库,想知道能否直接将字符串形式的运算符转为可执行的运算符字面量。
现有实现代码
char[] operator = // "+" or "<" or "<=" etc if (operator.length == 1) { switch (operator[0]) { case '+': if (a instanceof Double || b instanceof Double) { result = a.doubleValue() + b.doubleValue(); } else if (a instanceof Long && b instanceof Long) { result = a.longValue() + b.longValue(); } break; case '-': if (a instanceof Double || b instanceof Double) { result = a.doubleValue() - b.doubleValue(); } else if (a instanceof Long && b instanceof Long) { result = a.longValue() - b.longValue(); } break; case '*': if (a instanceof Double || b instanceof Double) { result = a.doubleValue() * b.doubleValue(); } else if (a instanceof Long && b instanceof Long) { result = a.longValue() * b.longValue(); } break; case '^': if (a instanceof Double || b instanceof Double) { result = Double.valueOf(Math.pow(a.doubleValue(), b.doubleValue())); } else if (a instanceof Long && b instanceof Long) { result = (long) Math.pow(a.longValue(), b.longValue()); } break; case '/': if (b.doubleValue() == 0) { throw new UnsupportedOperationException("Cannot divide by zero"); } if (a instanceof Double || b instanceof Double) { result = a.doubleValue() / b.doubleValue(); } else if (a instanceof Long && b instanceof Long) { result = a.longValue() / b.longValue(); } break; case '>': resultDecorator.setTypeOfexpresion(EvaluatorConstants.Boolean); if (a instanceof Double || b instanceof Double) { result = a.doubleValue() > b.doubleValue() ? 1 : 0; } else if (a instanceof Long && b instanceof Long) { result = a.longValue() > b.longValue() ? 1 : 0; } break; case '<': resultDecorator.setTypeOfexpresion(EvaluatorConstants.Boolean); if (a instanceof Double || b instanceof Double) { result = a.doubleValue() < b.doubleValue() ? 1 : 0; } else if (a instanceof Long && b instanceof Long) { result = a.longValue() < b.longValue() ? 1 : 0; } break; } } else if (operator.length == 2) { resultDecorator.setTypeOfexpresion(EvaluatorConstants.Boolean); switch (new String(operator)) { case ">=": if (a instanceof Double || b instanceof Double) { result = a.doubleValue() >= b.doubleValue() ? 1 : 0; } else if (a instanceof Long && b instanceof Long) { result = a.longValue() >= b.longValue() ? 1 : 0; } break; case "<=": if (a instanceof Double || b instanceof Double) { result = a.doubleValue() <= b.doubleValue() ? 1 : 0; } else if (a instanceof Long && b instanceof Long) { result = a.longValue() <= b.longValue() ? 1 : 0; } break; case "==": if (a instanceof Double || b instanceof Double) { result = a.doubleValue() == b.doubleValue() ? 1 : 0; } else if (a instanceof Long && b instanceof Long) { result = a.longValue() == b.longValue() ? 1 : 0; } break; } }
解答
Java作为静态编译型语言,无法直接将字符串/char[]形式的运算符转换为原生运算符字面量(比如把字符串"+"直接变成代码里的+符号),但可以通过策略模式封装运算逻辑,彻底消除重复代码,实现简洁的动态执行效果,且完全不依赖第三方库。
优化方案
- 定义统一运算接口
封装所有运算的执行逻辑,统一输入输出:
interface Operator { Object apply(Number a, Number b); }
- 预定义运算符映射表
将每个运算符字符串与对应的运算逻辑绑定,集中管理所有运算:
private static final Map<String, Operator> OPERATOR_MAP = new HashMap<>(); static { // 算术运算符 OPERATOR_MAP.put("+", (a, b) -> { if (a instanceof Double || b instanceof Double) { return a.doubleValue() + b.doubleValue(); } else { return a.longValue() + b.longValue(); } }); OPERATOR_MAP.put("-", (a, b) -> { if (a instanceof Double || b instanceof Double) { return a.doubleValue() - b.doubleValue(); } else { return a.longValue() - b.longValue(); } }); OPERATOR_MAP.put("*", (a, b) -> { if (a instanceof Double || b instanceof Double) { return a.doubleValue() * b.doubleValue(); } else { return a.longValue() * b.longValue(); } }); OPERATOR_MAP.put("/", (a, b) -> { if (b.doubleValue() == 0) { throw new UnsupportedOperationException("Cannot divide by zero"); } if (a instanceof Double || b instanceof Double) { return a.doubleValue() / b.doubleValue(); } else { return a.longValue() / b.longValue(); } }); OPERATOR_MAP.put("^", (a, b) -> { double powResult = Math.pow(a.doubleValue(), b.doubleValue()); return (a instanceof Double || b instanceof Double) ? powResult : (long) powResult; }); // 比较运算符 OPERATOR_MAP.put(">", (a, b) -> { boolean result = (a instanceof Double || b instanceof Double) ? a.doubleValue() > b.doubleValue() : a.longValue() > b.longValue(); return result ? 1 : 0; }); OPERATOR_MAP.put("<", (a, b) -> { boolean result = (a instanceof Double || b instanceof Double) ? a.doubleValue() < b.doubleValue() : a.longValue() < b.longValue(); return result ? 1 : 0; }); OPERATOR_MAP.put(">=", (a, b) -> { boolean result = (a instanceof Double || b instanceof Double) ? a.doubleValue() >= b.doubleValue() : a.longValue() >= b.longValue(); return result ? 1 : 0; }); OPERATOR_MAP.put("<=", (a, b) -> { boolean result = (a instanceof Double || b instanceof Double) ? a.doubleValue() <= b.doubleValue() : a.longValue() <= b.longValue(); return result ? 1 : 0; }); OPERATOR_MAP.put("==", (a, b) -> { boolean result = (a instanceof Double || b instanceof Double) ? Double.compare(a.doubleValue(), b.doubleValue()) == 0 : a.longValue() == b.longValue(); return result ? 1 : 0; }); }
- 简化主执行逻辑
直接通过映射表获取运算符并执行,彻底去掉冗长的switch分支:
char[] op = // 输入的运算符char数组 String opStr = new String(op); Operator operator = OPERATOR_MAP.get(opStr); if (operator == null) { throw new UnsupportedOperationException("Unsupported operator: " + opStr); } // 设置布尔类型标记 if (opStr.matches("[<>]=?|==")) { resultDecorator.setTypeOfexpresion(EvaluatorConstants.Boolean); } // 执行运算 result = operator.apply(a, b);
优化效果
- 消除了大量重复的类型判断和分支代码,逻辑更清晰
- 主执行逻辑极度简化,可读性大幅提升
- 新增运算符只需在映射表中添加对应实现,扩展性极强
- 完全基于Java原生API实现,无任何第三方依赖
内容的提问来源于stack exchange,提问作者Nagappa L M
相关产品推荐
相关产品推荐

