use relational operators in switch

2019-01-19 22:20发布

Is there a way to use relational operators (<,<=,>,>=) in a switch statement?

int score = 95;

switch(score)  {
   case (score >= 90):
      // do stuff
}

the above example (obviously) doesn't work

7条回答
太酷不给撩
2楼-- · 2019-01-19 23:21

Obviously, this is not possible as a language construct. But, just for fun, we could implement it by ourselves!

public class Switch<T, V> {

    public static interface Action<V> {
        V run();
    }

    private final T value;
    private boolean runAction = false;
    private boolean completed = false;
    private Action<V> actionToRun;

    public Switch(T value) {
        this.value = value;
    }

    static public <T, V> Switch<T, V> on(T value) {
        return new Switch<T, V>(value);
    }

    public Switch<T, V> ifTrue(boolean condition) {
        runAction |= condition;
        return this;
    }

    public Switch<T, V> ifEquals(T other) {
        return ifTrue(value.equals(other));
    }

    public Switch<T, V> byDefault(Action<V> action) {
        this.actionToRun = action;
        return this;
    }

    public Switch<T, V> then(Action<V> action) {
        if (runAction && !completed) {
            actionToRun = action;
            completed = true;
        }
        return this;
    }

    public V getResult() {
        if (actionToRun == null) {
            throw new IllegalStateException("none of conditions matched and no default action was provided");
        }
        return actionToRun.run();
    }
}

Switch accepts any value to switch on and then provides functionality to match over boolean conditions (ifTrue method) or by exact matches (ifEquals method). Providing a value to switch on is needed just for the latter feature.

After building the conditions, user invokes getResult to obtain the result.

For example, we could create a method that tells us what it thinks about our score:

String tellMeMyScore(int score) {
    return Switch.<Integer, String> on(score).byDefault(new Action<String>() {
        public String run() {
            return "really poor score";
        }
    }).ifTrue(score > 95).then(new Action<String>() {
        public String run() {
            return "you rock!";
        }
    }).ifTrue(score > 65).then(new Action<String>() {
        public String run() {
            return "not bad, not bad";
        }
    }).ifEquals(42).then(new Action<String>() {
        public String run() {
            return "that's the answer!";
        }
    }).getResult();
}

This simple test:

for (int score : new int[] { 97, 85, 66, 55, 42, 32, 4 }) {
    System.out.println(score + ": " + tellMeMyScore(score));
}

Prints out:

97: you rock!
85: not bad, not bad
66: not bad, not bad
55: really poor score
42: that's the answer!
32: really poor score
4: really poor score
查看更多
登录 后发表回答