Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I map a String to a method in java?

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?

like image 304
Derek Avatar asked Jul 17 '11 01:07

Derek


People also ask

Can we use map method on string?

Map() function can also be used to remove the spaces between the words of a string.

Can I convert a string to map in Java?

We can also convert an array of String to a HashMap. Suppose we have a string array of the student name and an array of roll numbers, and we want to convert it to HashMap so the roll number becomes the key of the HashMap and the name becomes the value of the HashMap. Note: Both the arrays should be the same size.

How do you add a string value to a string map?

Maps are associative containers that store elements in a specific order. It stores elements in a combination of key values and mapped values. To insert the data in the map insert() function in the map is used.

Does map have get method?

The get() method of Map interface in Java is used to retrieve or fetch the value mapped by a particular key mentioned in the parameter. It returns NULL when the map contains no such mapping for the key.


2 Answers

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;
    }
  });
}};
like image 72
Ionuț G. Stan Avatar answered Sep 28 '22 09:09

Ionuț G. Stan


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.

like image 40
Ben Avatar answered Sep 28 '22 11:09

Ben