At the risk of this being an opinion based question, would creating a Map/dictionary where the keys are predicates and the values the action to be made be a good and viable substitute for switch case?
For example (following Java Map) :
Map.of(predicate1, action1, ... predicateN, actionN)
.entrySet().stream()
.filter(e -> e.getKey()).findAny()
.ifPresentOrElseThrow().getValue();
It's an interesting approach, I sometimes do it for filters or mappers. The only thing I would change would be to avoid using a Map
if you don't really need one (what would be the hashcode of your Predicate - it can be looked up, but still, it's not super straightforward).
Instead, you can put the Predicate and the Consumer in some sort of Pair<>
or Tuple<>
, or even create your own structure:
record PossibleAction<T>(
Predicate<T> predicate,
Consumer<T> action
) {
// if you use a custom structure you can define these methods
// and use .appliesFor(data) instead of using .getPredicate().test(data)
public boolean appliesFor(T data) {
return predicate.test(data);
}
public void apply(T data) {
action.accept(data);
}
}
Now you can have a list of these PossibleActions
:
List<PossibleAction<String>> actions = List.of(
new PossibleAction<>(s -> s.contains("A"), s -> System.out.println("1") ),
new PossibleAction<>(s -> s.contains("B"), s -> System.out.println("2") ),
new PossibleAction<>(s -> s.contains("C"), s -> System.out.println("3") )
);
And you can use this, as pointed out by you in the initial post:
void performActions(String data) {
actions.stream()
.filter(a -> a.appliesFor(data))
.forEach(a -> a.apply(data));
}