java - 用 java lambdas 重构一个 switch case

标签 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);

方法 1:使用多态性

public interface Operation {
    void performOperation(int a, int b);
}

然后用可用的实现填充映射:

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

然后我可以在需要执行操作时引用 map 。

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

方法 2:使用枚举

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

这种方法实际上是两者中更好的,但我在 Java 8 中看到了另一个例子,我想使用类似这样的方法

由于所有这些都遵循我尝试使用函数式接口(interface)和 map 的模式

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

但这又具有第一种方法的缺点,所以想看看我是否可以像使用 Enum 实现一样使用 lambda 我想利用 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

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

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

Map<String, TriFunction<String, Integer, Integer, Operation>> map
= new HashMap<>();

最佳答案

你已经在那里了。如果您有一个与您的接口(interface)具有相同签名的方法,您也可以将它传递给您的操作存储库,例如:

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

关于java - 用 java lambdas 重构一个 switch case,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33603856/

相关文章:

java - Clojure/Java Mandelbrot 分形绘图

java - 无法解决 Eclipse "Archive for required library..."问题

java - Enum 实现 lambda 可能接口(interface)的简写符号

amazon-web-services - 如何在 aws kinesis 数据分析的 cloudformation 中将目标设置为 lambda

c++ - Lambda(通过引用与按值将 lambda 传递给函数)

java - 在 Java 套接字中关闭流的正确方法

java - 使用谷歌应用引擎上传图片的一步上传

java - playframework1.2.4中的XSS预防

c# - 循环内的外部变量如何与 lambda 一起使用?

python - 在 python 中定义 @classmethod lambda