用java lambdas重构一个switch case

Sud*_*eer 10 java lambda

我试图重新考虑遗留代码,在这种情况下,我有一个巨大的switch case,它决定了要执行的命令

switch(operation)
case addition  : return add(int a, String b, String c);
case multiply  : return multiply(int a, int b);
case substract : return substract(int a, int b);
Run Code Online (Sandbox Code Playgroud)

方法1:使用多态性

public interface Operation {
    void performOperation(int a, int b);
}
Run Code Online (Sandbox Code Playgroud)

然后使用可用的实现填充地图:

Map<Key, Operation> actions = new HashMap<>();
actions.add(addition, new addOperation());
actions.add(multiply, new multiplyOperation());
actions.add(substract, new substractOperation());
Run Code Online (Sandbox Code Playgroud)

然后我可以在需要执行操作时参考地图.

我对这种方法的问题是我必须创建大量的类/匿名类

方法2:使用Enum

public enum MyKeyEnum {
    ADDITION {
        public void performOperation(int a, int b) {
            // Perform addition
        }
    },
    MULTIPLY {
        public void performOperation(int a, int b) {
            // Perform Multiplication
        }
    };

    public abstract void performOperation(int counter, String dataMain, String dataSub);
    }
Run Code Online (Sandbox Code Playgroud)

这种方法实际上更好,但我在Java 8中看到了另一个eaxmple,并希望使用类似的东西

由于所有这些都遵循一种模式,我尝试使用功能接口和地图

final static Map<String, Supplier<IAction>> map = new HashMap<>();
static {
    map.put("add", Addition::new);
    map.put("multiply", Multiply::new);
}
public static void main(String[] args) throws Exception {
    Supplier<IAction> action = map.get("add");
    System.out.println(action.get().performAction(10,10));

    action = map.get("multiply");
    System.out.println(action.get().performAction(10,10));
}
Run Code Online (Sandbox Code Playgroud)

但这又有第一种方法的缺点,所以想看看我是否可以像使用Enum实现一样使用lambdas在Java 8中提供了一个部分函数实现,我想利用它:

BiFunction<Integer, Integer, Integer> minus = (x, y) -> x - y;
Function<Integer, Integer> subtractor = partial(minus, 10);
System.out.println(subtractor.apply(4)); // 6
Run Code Online (Sandbox Code Playgroud)

因为BiFunction只接受了2个参数我创建了一个Trifuction

@FunctionalInterface
interface TriFunction<T, U, V, R> {
    R apply(T a, U b, V c);
}

public static <T, U, V, R> Function<V, R> partial(TriFunction<T, U, V, R> f, T x, U y) {
    return (z) -> f.apply(x, y, z);
}
Run Code Online (Sandbox Code Playgroud)

这将在一定程度上解决问题,但我无法弄清楚如何将其添加到地图并动态传递值

Map<String, TriFunction<String, Integer, Integer, Operation>> map
= new HashMap<>();
Run Code Online (Sandbox Code Playgroud)

Flo*_*own 8

你已经在那里了.如果您的方法具有与您的界面相同的签名,您还可以将其传递到操作存储库,如:

Map<String, IntBinaryOperator> operations = new HashMap<>();
operations.put("add", Integer::sum);
operations.put("subtract", (a, b) -> a - b);
operations.put("multiply", (a, b) -> a * b);
//...
System.out.println(operations.get("multiply").applyAsInt(10, 20));
Run Code Online (Sandbox Code Playgroud)