if语句替代Java 8

时间:2016-06-06 10:15:07

标签: java if-statement lambda java-8

有这样的功能:

public void toDo(Req req){

    if(req.getSection().equals("A")) {
        return execA(req);
    }

    if(req.getSection().equals("B")) {
        return execB(req);
    }

    if(req.getSection().equals("N")) {
        return execN(req);
    }
}

我该如何简化它?一般的想法,如何排除 if 语句的识别类型的函数 - 字符串 - A,B,N 。 Java 8的任何解决方案都与Scala模式匹配?

3 个答案:

答案 0 :(得分:8)

你不能只用一个简单的开关吗?

switch (req.getSection()){
    case "A" : execA(req);  break;
    case "B" : execB(req);  break;
    case "N" : execN(req);  break;
    default:  break;
}

答案 1 :(得分:4)

除了the switch solution,适用于字符串和int值,您可以使用Map

Map<String,Consumer<Req>> handlers;
{
    handlers.put("A", req -> execA(req));
    handlers.put("B", req -> execB(req));
    handlers.put("N", req -> execN(req));
}
Consumer<Req> defaultBehavior=req-> {
    throw new IllegalArgumentException(req.getSection());
};
public void toDo(Req req) {
    handlers.getOrDefault(req.getSection(), defaultBehavior).accept(req);
}

除了支持其他键类型之外,它还允许在运行时组合地图,例如使用由不同的,可能是动态加载的模块等提供的处理程序。

答案 2 :(得分:0)

使用反射和类上的方法数组,可以应用过滤器(if-replacement),映射(返回值)和可选地定义默认值(orElse)。

如果病例数量巨大或动态,这种方法可能会很好。但是对于你的特殊情况,我认为这太过分了。更好地坚持交换机案例解决方案。

public Optional<Object> toDo(Req req) {
    return Stream.of(this.getClass().getMethods())
                 .filter(m -> m.getName().equals("exec" + req.getSection()))
                 .map(this::invokeUnchecked).findFirst();
}

private Object invokeUnchecked(final Method m) {
    try {
        return m.invoke(this);
    } catch (IllegalAccessException| InvocationTargetException e) {
        throw new RuntimeException(e);
    }
}

如果您不想使用可选项,则必须使用.findFirst().orElse(() -> ...)

声明默认值