英文:
Using Map/Dictionary as an alternative to switch case
问题
在冒这个问题可能是基于观点的风险下,创建一个将键作为谓词而值作为要执行的操作的映射/字典是否可以作为替代switch case的良好且可行的选择?
例如(以下为Java映射):
Map.of(predicate1, action1, ... predicateN, actionN)
.entrySet().stream()
.filter(e -> e.getKey()).findAny()
.ifPresentOrElseThrow().getValue();
英文:
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();
答案1
得分: 1
以下是翻译好的部分:
"这是一个有趣的方法,有时我会用它来进行过滤或映射操作。我唯一想改变的是,如果不是真正需要的话,尽量避免使用Map
(谓词的哈希码可以查找,但仍然不是非常直观的)。
相反,你可以将谓词和消费者放入Pair<>
或Tuple<>
之类的结构中,甚至创建自己的结构:
record PossibleAction<T>(
Predicate<T> predicate,
Consumer<T> action
) {
// 如果使用自定义结构,可以定义这些方法
// 并使用 .appliesFor(data) 代替 .getPredicate().test(data)
public boolean appliesFor(T data) {
return predicate.test(data);
}
public void apply(T data) {
action.accept(data);
}
}
现在你可以拥有一个这些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"))
);
你可以像在初始帖子中提到的那样使用它:
void performActions(String data) {
actions.stream()
.filter(a -> a.appliesFor(data))
.forEach(a -> a.apply(data));
}
希望这对你有帮助!
英文:
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));
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论