Reputation: 313
I am trying to make my code more efficient and replace a bunch of if statements that I wrote. My program so far basically checks what operator (such as +, -, etc) is entered and then computes it. For example 1 + 5 gives 6. When the program evaluates the symbol between the number (the "+" in my example) it will check what the operator is and then proceed accordingly. For example if it's a "+", it will take the 1 and add 5. The code works like this:
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];
I am wondering if it is possible to replace this whole block with some kind of statement that will detect the operator from the String and convert it into an operation? I realize for a few operators it is probably easier to use the switch statements but I have a lot of them and there is a 5-10ms difference between evaluating the operator at the top of the switch statements and at the bottom.
Upvotes: 6
Views: 1330
Reputation: 8640
if you are not going with java 8 you could do something like that
public interface Op{
int execute(int[] values);
}
public class Add implements Op{
public int execute(int[] values){
return values[0] + values[1];
}
}
then all what you need is define your operations map and populate it
private final Map<String, Op> operations = new HashMap<>();
operations.put("+", new Add());
then you can use it by calling operations.get(op).execute(args)
this structure will allow you to support operations with one two or even 100 parameters
Upvotes: 0
Reputation: 3809
The answer is the Strategy Pattern - you already have the nice Java 8 example, so here is the pre-lambda version (which also shows why lambdas were sorely needed):
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));
}
}
Upvotes: 2
Reputation: 361635
In Java 8, you could use a map of lambda functions:
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]);
There's more indirection here, but it will give you O(1) amortized lookup time.
Upvotes: 12