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