【问题标题】:Can I map a String to a method in java?我可以将字符串映射到java中的方法吗?
【发布时间】:2011-10-06 23:18:50
【问题描述】:

我正在用 Java 编写表达式求值器。我希望能够添加更多运算符(我目前只有 (、)、+、-、*、/ 和 ^)。目前,我的代码如下所示:

case '+':  
return a+b;  
case '-':  
return a-b;  
case '*':  
return a*b;  
...

这适用于我的代码,因为我只有几个运算符。但是,如果我要添加更多运算符,代码会变得混乱。我正在寻找一种将运算符(由字符串表示)映射到方法的方法。例如,“ln”会映射到 Math.log(),“^”会映射到 Math.pow(),等等。

我该怎么做呢?如果不可行,有什么替代方案?

【问题讨论】:

标签: java string methods map


【解决方案1】:

除非您想使用反射,否则不可能。没有反射的解决方案可能如下所示:

public interface Operation {
  int apply(int... operands);
}

public abstract class BinaryOperation implements Operation {
  @Override
  public int apply(int... operands) {
    return apply(operands[0], operands[1]);
  }

  abstract int apply(int a, int b);
}

Map<String, Operation> operations = new HashMap<String, Operation>() {{
  put("+", new Operation() {
    @Override
    public int apply(int... operands) {
      return operands[0] + operands[1];
    }
  });
  put("-", new BinaryOperation() {
    @Override
    public int apply(int a, int b) {
      return a - b;
    }
  });
}};

【讨论】:

  • 这仅在所有运算符采用相同数量的参数时才有效。不过,它比我现在拥有的要好得多。谢谢。
  • 您可以让Operation.apply 需要可变数量的参数,或者List 的参数。
  • @Derek,这也可以使用enum 以类似的方式完成。
  • 我喜欢有可变数量的参数的想法。
【解决方案2】:

你可以使用模板方法。

public enum Functions {
    ADD() {
        @Override public int execute(int a, int b) {
            return a+b;
        }
    },
    SUB() {
        @Override public int execute(int a, int b) {
            return a-b;
        }
    };

   //Template method
   public abstract int execute(int a, int b);
}

然后在字符串和枚举之间映射Map&lt;String, Functions&gt; functionMap 所以如果你想添加你可以做functionMap.put("+", Functions.ADD); 然后拨打functionMap.get("+").execute(a,b);

如果不同的函数采用不同数量的参数,我想你也可以使用可变参数。 public abstract int execute (Integer... inputs);

这个例子是根据Making the Most of Java 5.0: Enum Tricks和@duffymo所说的修改而来的。

【讨论】:

  • 此解决方案的缺点是,您必须在要添加新操作时修改枚举。臭名昭著的表达问题:en.wikipedia.org/wiki/Expression_problem
  • @Ionut G. Stan 好吧,没有人会阻止他将其定义为接口,并在启动时加载一些包含定义的文件,从中创建匿名类并将它们存储在 Hashmap 中
  • @Voo,我相信这基本上会将我的答案转换为@Ionuț G. Stan 的。
【解决方案3】:

基于上面的 Operation 建议,Map&lt;String, Operation&gt; 将通过查找来管理它。

【讨论】:

    【解决方案4】:

    我认为您的设置是最佳设置,因为我想不出在 java 中轻松做到这一点的方法,尽管在像 c/c++ 这样的语言中,您可以轻松地将字符串映射到函数指针,但我认为没有等价的这在Java AFAIK中。不过 switch 语句的美妙之处在于它们实际上避免了混乱,因为在视觉上你可以很容易地看到 switch 语句的大小写,并且只需寻找你想要的适当大小写(尽管对于你创建的字符串,你需要一个巨大的 if 级联,因为 = = 运算符在 java 中未重载以进行字符串比较)。

    编辑:请参阅 Ryan Stewarts 评论,他们使用 OOP 方式来做你想做的事。尽管在某些情况下这似乎比您的 switch 语句更混乱。

    【讨论】:

    • 是的,在大多数 Java 版本中,您无法打开字符串
    • @Andrew,当您遇到开始看起来难看的字符串时。 if (str.equals("case1")).... else if (str.equals("case2"))...
    猜你喜欢
    • 1970-01-01
    • 2011-11-21
    • 2023-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多