目录

概述

  这篇博文用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

结尾

  写着玩的代码,写完自己都想吐槽了。看着用了一些高级的写法,不仅完全没有解决什么问题,而且还带来了很大的代码复杂性。

10-07 16:09