Java:用lambdas替换交换机。 值得?
在检查事件时,使用带有开关或代码的代码块是一件常见的事情。 当简单时它可以是干净的代码,但似乎仍然有比所需要的更多的行,并可以使用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是最差的,但是对于性能不重要的情况,lambda版本比switch / if块更短。
那么,你怎么看? 也许有一种比这更短的Kotlin方法,我只专注于java,我喜欢Kotlin,但编译对于我的项目来说仍然太慢。
当块必须返回一个特定的值时,可以使用类似的工具类。
仅供参考,lambdas类是在这里,我没有检查错误,只是迅速为这个例子:
public class With { private final T id; private boolean actionFound; private With(T id) { this.id = id; } public static With with(T id) { return new With(id); } public With 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(); } }
正如一对夫妇所说,用复合方法替代switch
效率不高。 根据你的使用情况,使用你的实现甚至可能是值得的。
有趣的是,Oracle实际上正计划在switch
语句中实现lambdaexpression式,正如最近的JEP中所看到的那样。
例:
String formatted = switch (s) { case null -> "(null)"; case "" -> "(empty)"; default -> s; }
该开关更灵活,可以用不同数量的参数调用函数,或者调用多个函数。 您还可以更容易地指出两个案件导致相同的行为。 更快的事实只是一个奖金。
所以从这个意义上说,我不确定你的With
类是真的添加了什么。
但是,交换机可以使用的数量有限。 也许你的With
类将被certificate是更有用的,如果你要传递它的谓词而不是执行简单的引用平等,例如:
public With when(Predicate 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);
用lambda替换开关。 值得?
没有。
因为在OO语言中, switch
或if
/ else
级联的替换是多态 ,而不是“流利的API”。
一个选项是声明static final Map
。 那么你只需要EXPECTED_ID_TO_ACTION.getOrDefault(actionId, DEFAULT_ACTION).execute()
,把丑陋的switch
或多个( if
s)变成一行。