【问题标题】:Replacing If Statements?替换 If 语句?
【发布时间】:2015-02-11 17:19:12
【问题描述】:

我正在尝试使我的代码更高效,并替换我编写的一堆 if 语句。到目前为止,我的程序基本上检查输入了哪些运算符(例如 +、- 等),然后计算它。例如 1 + 5 给出 6。当程序计算数字之间的符号(在我的示例中为“+”)时,它将检查运算符是什么,然后相应地继续。例如,如果它是一个“+”,它将接受 1 并添加 5。代码如下所示:

switch (op) {
    case "+": // Addition
        return args[0] + args[1]; 
    case "-": // Subtraction
        return args[0] - args[1]; 
    case "*": // Multiplication
        return args[0] * args[1]; 
    case "/": // Division
        return args[0] / args[1]; 

我想知道是否可以用某种语句替换整个块,该语句将从字符串中检测运算符并将其转换为操作?我意识到对于一些运算符来说,使用 switch 语句可能更容易,但我有很多它们,并且在 switch 语句的顶部和底部评估运算符之间存在 5-10 毫秒的差异。

【问题讨论】:

  • 具有很多情况的 Switch 语句已经经过编译器优化,性能与基于哈希的查找相当,或者至少比线性 if/else 搜索要好得多。

标签: java if-statement switch-statement


【解决方案1】:

在 Java 8 中,您可以使用 lambda 函数的映射:

Map<String, IntBinaryOperator> operators = new HashMap<>();

operators.put("+", (a, b) -> a + b);
operators.put("-", (a, b) -> a - b);
operators.put("*", (a, b) -> a * b);
operators.put("/", (a, b) -> a / b);

...

return operators.get(op).apply(args[0], args[1]);

这里有更多的间接性,但它会给你 O(1) 分摊的查找时间。

【讨论】:

  • 感谢您的帮助,我将在今天晚些时候进行测试。有没有办法也可以与函数一起使用?就像操作是“sqrt”一样,我希望它调用 Math.sqrt(args[0])。
  • @ThomasPaine 对于平方根,您可以尝试 operator.put("sqrt", (a, b) -> Math.sqrt(args[0])。不过,您应该尝试寻找使用除 IntBinaryOperator 之外的不同功能接口。
  • 这种哈希查找会比编译器优化的开关查找更高效吗?
  • @The111 在这种特殊情况下,可能不是。 stackoverflow.com/questions/22110707/…(不过我认为这不是重点。)
  • @Radiodef OP的第一句话说提高效率是他的目的。
【解决方案2】:

答案是Strategy Pattern - 你已经有了不错的 Java 8 示例,所以这里是 lambda 之前的版本(这也说明了为什么迫切需要 lambda):

public class CodeTest {

    private static interface ArithmeticStrategy {
        public double apply(double arg1, double arg2);
    }

    private static class AddArithmeticStrategy implements ArithmeticStrategy {
        @Override
        public double apply(double arg1, double arg2) {
            return arg1 + arg2;
        }
    }

    // ... other operations

    private static Map<String, ArithmeticStrategy> OPS = new HashMap<>();
    static {
        OPS.put("+", new AddArithmeticStrategy());
    }

    public static void main(String[] args) {
        // Add two numbers and print the result
        System.out.println(
                OPS.get("+").apply(22.3, 35.4));
    }
}

【讨论】:

    【解决方案3】:

    如果你不使用 java 8,你可以做类似的事情

    public interface Op{
            int execute(int[] values);
        }
        public class Add implements Op{
            public int execute(int[] values){
                return values[0] + values[1];
            }
        }  
    

    那么您所需要的就是定义您的操作图并填充它

    private final Map<String, Op> operations = new HashMap<>();
    operations.put("+", new Add());
    

    然后你可以通过调用operations.get(op).execute(args)来使用它

    这种结构将允许您支持一个两个甚至 100 个参数的操作

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-12
      • 1970-01-01
      • 1970-01-01
      • 2013-10-27
      相关资源
      最近更新 更多