概述
这篇博文用lambda表达式和三目运算符模拟 if-elseIf-else 形式作为反面教材来阐述这类花式作死,仅供娱乐,博大家一笑。
最后达到的效果如下:
cIf(cond1, () -> { //开头的 if
//do action 1
}).cElseIf(() -> cond2, () -> { //对 cond2 条件求值的 else if
//do action 2
}).cElseIf(cond3, () -> { //对 cond3 无条件求值的 else if
//do action 3
}).cElse(() -> { //最后的 else
//do action 4
});
实现
采用构造器配合方法链来实现,省略空指针检测,主要类如下:
/**
* 整个语句块的构造器
*/
class IfBuilder {
/* 隐藏构造方法 */
private IfBuilder() {
}
/**
* @param predicate 无条件求值的断言
* @param action 要执行的动作
* @return 同下面 cIf
*/
public static IfBuilder cIf(boolean predicate, Runnable action) {
return cIf(() -> predicate, action); //转为条件求值的断言,调用重载方法 cIf
}
/**
* @param predicate 条件求值的断言
* @param action 要执行的动作
* @return 如果断言求值为 true, 就返回默认什么都不做的 builder,否则返回具有后续 elseIf 和 else 功能的 builder
*/
public static IfBuilder cIf(Supplier<Boolean> predicate, Runnable action) {
return predicate.get() //对断言求值
?
((Supplier<IfBuilder>) () -> { //断言的结果是 true, 求值 action,并返回一个没有实现功能的空 builder
action.run();
return new IfBuilder();
}).get()
:
new IfBuilder() { //断言的结果是 false,不求值 action, 返回一个具有后续 elseIf 和 else 功能的 builder
/* 表示是否有断言返回 true 的标志变量 */
private boolean elseIfFlag = false;
@Override
public IfBuilder cElseIf(Supplier<Boolean> b, Runnable r) {
/* 如果断言为 true 就求值 r, 然后把 elseIfFlag 变为 true,返回一个空的 builder; 否则,直接返回自身 */
return b.get() ? ((Supplier<IfBuilder>) () -> {
r.run();
elseIfFlag = true;
return new IfBuilder();
}).get() : this;
}
@Override
public IfBuilder cElseIf(boolean b, Runnable r) {
return cElseIf(() -> b, r);
}
@Override
public void cElse(Runnable r) {
/* 当且仅当之前没有 elseIf 满足的情况下,求值 r */
((Supplier<IfBuilder>) () -> elseIfFlag ? this : ((Supplier<IfBuilder>) () -> {
r.run();
return this;
}).get()).get();
}
};
}
/* 对断言条件求值的默认 else if, 无动作*/
public IfBuilder cElseIf(Supplier<Boolean> b, Runnable r) {
return this;
}
/* 对断言无条件求值的默认 else if, 无动作*/
public IfBuilder cElseIf(boolean b, Runnable r) {
return this;
}
/* 默认 else, 无动作*/
public void cElse(Runnable r) {
}
}
示例
示例代码如下,其中 i 和 j 每次用随机数生成
for (int x = 0; x < 10; x++) {
int i = new Random().nextInt() % 4;
int j = new Random().nextInt() % 4;
cIf(i == 0 || j == 0, () -> {
System.out.println(i + " " + j + " : i == 0 || j == 0");
}).cElseIf(() -> i < j, () -> {
System.out.println(i + " " + j + " : i < j");
}).cElseIf(i > j, () -> {
System.out.println(i + " " + j + " : i > j");
}).cElse(() -> {
System.out.println(i + " " + j + " : i = j");
});
}
示例输出:
-3 -1 : i < j
3 -3 : i > j
2 -2 : i > j
0 -1 : i == 0 || j == 0
-1 -2 : i > j
-1 -1 : i = j
-1 -2 : i > j
0 0 : i == 0 || j == 0
2 1 : i > j
2 1 : i > j
结尾
写着玩的代码,写完自己都想吐槽了。看着用了一些高级的写法,不仅完全没有解决什么问题,而且还带来了很大的代码复杂性。