使用Map/字典作为替代switch case。

huangapple go评论70阅读模式
英文:

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&lt;&gt; or Tuple&lt;&gt;, or even create your own structure:

record PossibleAction&lt;T&gt;(
		Predicate&lt;T&gt; predicate,
		Consumer&lt;T&gt; 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&lt;PossibleAction&lt;String&gt;&gt; actions = List.of(
	new PossibleAction&lt;&gt;(s -&gt; s.contains(&quot;A&quot;), s -&gt; System.out.println(&quot;1&quot;) ),
	new PossibleAction&lt;&gt;(s -&gt; s.contains(&quot;B&quot;), s -&gt; System.out.println(&quot;2&quot;) ),
	new PossibleAction&lt;&gt;(s -&gt; s.contains(&quot;C&quot;), s -&gt; System.out.println(&quot;3&quot;) )
);

And you can use this, as pointed out by you in the initial post:

void performActions(String data) {
	actions.stream()
			.filter(a -&gt; a.appliesFor(data))
			.forEach(a -&gt; a.apply(data));
}

huangapple
  • 本文由 发表于 2023年4月19日 16:09:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76052119.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定