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语言中, switchif / else级联的替换是多态 ,而不是“流利的API”。

一个选项是声明static final Map EXPECTED_ID_TO_ACTION 。 那么你只需要EXPECTED_ID_TO_ACTION.getOrDefault(actionId, DEFAULT_ACTION).execute() ,把丑陋的switch或多个( if s)变成一行。