有这样的功能:
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模式匹配?
答案 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(() -> ...)