Java Enum Multiple Keys mapped to single method

Viewed 185

I am looking at this code from here:

enum Operator {
    ADD {
        @Override int execute(final int num1, final int num2) {
            return num1 + num2;
        }
    },
    SUBTRACT {
        @Override int execute(final int num1, final int num2) {
            return num1 - num2;
        }
    },
    MULTIPLY {
        @Override int execute(final int num1, final int num2) {
            return num1 * num2;
        }
    },
    DIVIDE {
        @Override int execute(final int num1, final int num2) {
            if (num2 != 0) {
                return num1 / num2;
            } else {
                System.out.println("Can't divide by zero.");
            }
            return 0;
        }
    };

    abstract int execute(int num1, int num2);
}

public class EnumWithoutDefinedFunctions {
    public static void main(String[] args) {
        int num1 = 10;
        int num2 = 2;
        Operator operator = Operator.DIVIDE;
        int result = operator.execute(num1, num2);
        System.out.println("result: " + result);
    }
}

I am searching for a way to call same method with different keys. For example, both ADD and ADD2 should execute same implementation i.e.

ADD,ADD2 {
    @Override int execute(final int num1, final int num2) {
        return num1 + num2;
    }
},

However, the above change to the code results in the following error:

enter image description here

2 Answers

I have found a workaround not sure if this is the optimised solution i.e. create a method and then call the same for the keys requiring the same implementation:

public class EnumTest {
    enum Operator {
        ADD {
            @Override int execute(final int num1, final int num2) {
                return addImpl( num1,num2);
            }
        },
        ADD2 {
            @Override int execute(final int num1, final int num2) {
                return addImpl( num1,num2);
            }
        },
        SUBTRACT {
            @Override int execute(final int num1, final int num2) {
                return num1 - num2;
            }
        },
        MULTIPLY {
            @Override int execute(final int num1, final int num2) {
                return num1 * num2;
            }
        },
        DIVIDE {
            @Override int execute(final int num1, final int num2) {
                if (num2 != 0) {
                    return num1 / num2;
                } else {
                    System.out.println("Can't divide by zero.");
                }
                return 0;
            }
        };

        private static int addImpl(int num1, int num2){
            return num1 + num2;
        }

        abstract int execute(int num1, int num2);
    }

    public static void main(String[] args) {
        int num1 = 10;
        int num2 = 2;
        Operator operator = Operator.ADD2;
        int result = operator.execute(num1, num2);
        System.out.println("result: " + result);
    }
}

IMO you can improve the design by using the Functional Interface BiFunction.

Here is how the code looks like:

public class EnumTest {

    enum Operator implements BiFunction<Integer, Integer, Integer> {
        ADD(Operator::addImpl),
        ADD2 (Operator::addImpl),
        SUBTRACT((num1, num2) -> num1 - num2),
        MULTIPLY((num1, num2) -> num1 * num2),
        DIVIDE (Operator::divide);

        public static Integer divide(Integer num1, Integer num2) {
            if (num2 != 0) {
                return num1 / num2;
            } else {
                System.out.println("Can't divide by zero.");
            }
            return 0;
        }

       final BiFunction<Integer, Integer, Integer> biFunction;

       Operator(BiFunction<Integer, Integer, Integer> apply){
           this.biFunction = apply;
       }

       public Integer apply(Integer a, Integer b){
           return biFunction.apply(a, b);
       }

        private static int addImpl(int num1, int num2){
            return num1 + num2;
        }
    }
    public static void main(String[] args) {
        int num1 = 10;
        int num2 = 2;
        Operator operator = Operator.ADD2;
        int result = operator.apply(num1, num2);
        System.out.println("result: " + result);
    }
}

And can take advantage of the BiFunction interface to combine multiple operations nicely, like:

Function<Integer, Integer> multiplyBy2 = l -> 2 * l;
int result2 = Operator.ADD2.andThen(multiplyBy2).apply(num1, num2);
System.out.println(result2);

Output:

24
Related