Can I map a String to a method in java?

隐身守侯 提交于 2019-12-06 03:17:14

问题


I'm writing an expression evaluator in Java. I would like the ability to add more operators (I currently have only (, ), +, -, *, /, and ^). Currently, my code looks like this:

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

This works for my code because I have only a few operators. However, if I were to add more operators, the code would become cluttered. I am looking for a way to map an operator (represented by a String) to a method. For example, "ln" would be mapped to Math.log(), "^" would be mapped to Math.pow(), etc.

How would I go about doing this? If it's not feasible, what are some alternatives?


回答1:


Not possible unless you want to use reflection. A solution without reflection could look like this:

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;
    }
  });
}};



回答2:


You could use template methods.

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);
}

Then map between string and enum with Map<String, Functions> functionMap So if you want to add you can do functionMap.put("+", Functions.ADD); Then call functionMap.get("+").execute(a,b);

I suppose you could also use varargs if different functions take different numbers of arguments. public abstract int execute (Integer... inputs);

This example is modified from Making the Most of Java 5.0: Enum Tricks and what @duffymo said.




回答3:


Building on the Operation suggestion above, a Map<String, Operation> would manage it with a lookup.




回答4:


I think your setup is the optimal setup as I cannot think of a way to do this easily in java, although in a language like c/c++ you could easily map strings to function pointers but I don't think there's an equivalent of this in Java AFAIK. The beauty of switch statements though is that they actually avoid the clutter because visually you can easily see what the case of the switch statement is and just look for the appropriate case that you want (although for strings you made need a giant if cascade since == operator is not overloaded in java for string comparison).

Edit: See Ryan Stewarts comment, they use OOP ways of doing exactly what you want. Although that seems more cluttered than your switch statement in some cases.



来源:https://stackoverflow.com/questions/6721318/can-i-map-a-string-to-a-method-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!