我可以将字符串映射到java中的方法吗?

Posted

技术标签:

【中文标题】我可以将字符串映射到java中的方法吗?【英文标题】:Can I map a String to a method in 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(),等等。

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

【问题讨论】:

查看前几天的a similar question。 【参考方案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"))...

以上是关于我可以将字符串映射到java中的方法吗?的主要内容,如果未能解决你的问题,请参考以下文章

我可以将行/模型映射到由 SQLAlchemy 中的枚举列(或字符串列上的逻辑)键入的字典吗?

如何将 int 映射到 C/C++ 中的相应字符串

将整数映射到组合框中的自定义类的字符串

NHibernate 可以将 CLR“对象”类型映射到 SQL 类型吗?

如何将 JSON 映射到 java 模型类

如何将字符串中的所有数字映射到 Python 中的列表? [复制]