在检查事件时使用带有switch或if的代码块是常见的事情。它很简单,可以是干净的代码,但似乎仍然有比所需更多的行,并且可以使用lambdas进行简化。
阻止if:
if(action == ACTION_1){
doAction1();
} else if(action == ACTION_2){
doAction2();
} else {
doDefaultAction();
}
使用开关阻止:
switch(action){
case ACTION_1:
doAction1();
break;
case ACTION_2:
doAction2();
break;
default:
doDefaultAction();
}
使用下面的实用程序类With
阻止lambda:
with(action)
.when(ACTION_1, this::doAction1)
.when(ACTION_2, this::doAction2)
.byDefault(this::doDefaultAction)
使用lambdas的代码较少,但问题是:它比其他代码更容易阅读吗?更容易维护?关于性能lambda是最差的,但是对于性能不重要的情况,lambdas版本比switch / if块短。
那么,你怎么看?也许Kotlin的方式比这短,我只关注java,我喜欢Kotlin,但编译对我的项目来说仍然太慢。
当块必须返回特定值时,可以使用类似的实用程序类。
仅供参考,lambdas的类在这里,我没有检查错误,只是为了这个例子快速做到了:
public class With<T> {
private final T id;
private boolean actionFound;
private With(T id) {
this.id = id;
}
public static <T> With<T> with(T id) {
return new With<>(id);
}
public With<T> when(T expectedId, Action action) {
if (!actionFound && id == expectedId) {
actionFound = true;
action.execute();
}
return this;
}
public void byDefault(Action action) {
if (!actionFound) {
action.execute();
}
}
@FunctionalInterface
interface Action {
void execute();
}
}
答案 0 :(得分:2)
交换机更灵活,因为您可以使用不同数量的参数调用函数,或者调用多个函数。您还可以更轻松地表示两个案例何时导致相同的操作。它更快的事实只是一个奖励。
所以从这个意义上来说,我不确定你的With
班级真正添加了什么。
但是,switch可以使用的类型有限。如果你传递谓词而不是执行简单的引用相等,那么你的With
类可能会更有用,例如:
public With<T> when(Predicate<T> expected, Action action) {
if (!actionFound && expected.test(id)) {
actionFound = true;
action.execute();
}
return this;
}
样本用法:
final String test = "test";
with(test)
.when(String::isEmpty, this::doAction1)
.when(s -> s.length() == 3, this::doAction2)
.byDefault(this::doDefaultAction);
答案 1 :(得分:2)
正如一对夫妇所说,用复合方法替换switch
的效率较低。根据您的使用情况,使用您的实现甚至是值得的。
有趣的是,Oracle实际上计划在switch
语句中实现lambdas,如this recent JEP中所示。
示例:
String formatted = switch (s) {
case null -> "(null)";
case "" -> "(empty)";
default -> s;
}
答案 2 :(得分:1)
用lambdas替换开关。值得吗?
没有
因为在OO语言中,switch
或if
/ else
级联的替换是多态,而不是&#34;流畅的API&#34 ;
答案 3 :(得分:0)
执行此操作的一个选项是声明static final Map<T, Action> EXPECTED_ID_TO_ACTION
。然后你可以EXPECTED_ID_TO_ACTION.getOrDefault(actionId, DEFAULT_ACTION).execute()
将丑陋的switch
或多个if
变成一行。