Java支持批量累积运算的Calculator计算器实现需求与接口规范
Java批量累积运算计算器实现
功能说明
我们需要实现一款支持批量运算的Java计算器,工作逻辑如下:
- 首个运算接收操作符和两个操作数
- 后续运算自动将前一次运算结果作为当前运算的第一个操作数,仅需传入额外1个新操作数即可,非首个运算传入的第二个操作数会被自动忽略
- 支持
+、-、*、/四种运算 - 批量运算执行完成后(即使执行过程中抛出异常)会自动清空所有内部状态
完整实现代码
import java.util.ArrayList; import java.util.List; import java.util.Set; public class Calculator { // 合法操作符集合 private static final Set<String> VALID_OPERATIONS = Set.of("+", "-", "*", "/"); // 运算节点内部类,存储单步运算信息 private static class OpNode { String op; float num1; float num2; boolean isFirstOp; public OpNode(String op, float num1, float num2, boolean isFirstOp) { this.op = op; this.num1 = num1; this.num2 = num2; this.isFirstOp = isFirstOp; } } private final List<OpNode> opNodes = new ArrayList<>(); /** * 计算器公共构造方法 */ public Calculator () {} /** * 清除计算器的内部状态 */ public void cleanOperations () { opNodes.clear(); } /** * 向计算器内部状态添加新运算。 * 计算器采用累积运算逻辑:仅首个运算需要两个操作数,后续运算均使用累积值加1个额外新操作数计算,非首个运算传入的第二个操作数将被忽略。 * * @param operation 待添加的运算操作符,字符串类型,支持"+"、"-"、"*"、"/" * @param values 新运算的操作数,支持1个或2个,使用Java varargs可变参数特性 * @throws IllegalArgumentException 传入操作符不合法、操作数数量不足时抛出 */ public void addOperation(String operation , float ... values) { // 操作符合法性校验 if (!VALID_OPERATIONS.contains(operation)) { throw new IllegalArgumentException("不支持的操作符:" + operation); } boolean isFirst = opNodes.isEmpty(); // 操作数数量校验 if (isFirst && values.length < 2) { throw new IllegalArgumentException("首次运算需要至少2个操作数"); } if (!isFirst && values.length < 1) { throw new IllegalArgumentException("运算需要至少1个操作数"); } // 存储运算节点 if (isFirst) { opNodes.add(new OpNode(operation, values[0], values[1], true)); } else { opNodes.add(new OpNode(operation, 0, values[0], false)); } } /** * 执行计算器内部存储的所有批量运算。 * 执行完成后(即便执行过程中抛出异常),内部存储的操作数和运算都会被清空重置,计算器采用运算批量处理模式。 * @return 所有运算执行后的最终结果 * @throws ArithmeticException 运算出现非法值(如除零)时抛出 */ public float executeOperations () { float result = 0f; try { if (opNodes.isEmpty()) { return result; } // 执行首个运算 OpNode firstNode = opNodes.get(0); result = calcSingle(firstNode.op, firstNode.num1, firstNode.num2); // 执行后续累积运算 for (int i = 1; i < opNodes.size(); i++) { OpNode current = opNodes.get(i); result = calcSingle(current.op, result, current.num2); } return result; } finally { // 无论运算是否异常都清空状态 cleanOperations(); } } /** * 单步运算逻辑封装 */ private float calcSingle(String op, float a, float b) { switch (op) { case "+": return a + b; case "-": return a - b; case "*": return a * b; case "/": if (b == 0f) { throw new ArithmeticException("除零运算错误"); } return a / b; default: throw new IllegalArgumentException("不支持的操作符:" + op); } } /** * 输出计算器当前内部状态字符串,格式要求: * "[{+/ -/"/"/*}] value1_value2 [{+/ -/"/"/*}] value1 [{+/ -/"/"/*}] value1 {...}" * @return 计算器内部状态字符串 */ @Override public String toString () { StringBuilder sb = new StringBuilder("[STATE:"); for (OpNode node : opNodes) { sb.append("[").append(node.op).append("]"); if (node.isFirstOp) { sb.append(node.num1).append("_").append(node.num2); } else { sb.append(node.num2); } } sb.append("]"); return sb.toString(); } }
测试验证
上述实现可直接通过给定测试用例:
float EPSILON = 0.01f; Calculator calculator = new Calculator(); // 添加运算 calculator.addOperation("+", 4.5f, 6.8f); calculator.addOperation("-", 3.1f); calculator.addOperation("/", 6f); // 校验状态字符串 assertEquals("[STATE:[+]4.5_6.8[-]3.1[/]6.0]", calculator.toString()); // 执行运算 float result = calculator.executeOperations(); // 校验执行后状态清空 assertEquals("[STATE:]", calculator.toString()); // 校验运算结果误差符合要求 assertEquals(1.366f, result, EPSILON);
运算过程:(4.5 + 6.8 - 3.1) / 6 = 8.2 / 6 ≈ 1.3667,符合0.01误差范围要求。
内容的提问来源于stack exchange,提问作者rascadux
相关产品推荐
相关产品推荐

