gpt4 book ai didi

java - 大小写类型(带返回值的开关)

转载 作者:行者123 更新时间:2023-11-29 04:17:46 24 4
gpt4 key购买 nike

问题Switch over type in java考虑如何根据对象的类型打开要执行的代码。

现在我想要一个 case 语句,就像在许多函数式语言中使用的那样:

r = case x of
String s -> s
Int i -> toString i

也就是我要switch类型,也把switch语句当成一个表达式(即应该有结果)。

就像在 switch 中一样,应该允许多个 case 匹配,但评估将从头到尾检查并返回第一个匹配的值(如果没有匹配则返回 null)。

可以是this answer的样式对于上述使用 Java 8 功能特性的问题:

switchType(x,
caze(String.class, v -> print("String: " + v),
caze(Integer.class, v -> print("Int: " + v));

最佳答案

类似于this answer中的改编通过仅执行第一个匹配项来调整上述解决方案,可以添加一个额外的类型参数 R对于返回类型并使用 Function<T,R>而不是 Predicate<T> :

  public static <R> R caseType(Object obj, Function<Object, Optional<R>>... functions) {
for (Function<Object, Optional<R>> f : functions) {
Optional<R> res = f.apply(obj);
if (res.isPresent()) {
return res.get();
}
}
return null; // Default case (no match)
}

public static <T, R> Function<Object, Optional<R>> of(Class<T> cls, Function<T, R> f) {
// Wrap the function with a type check
return obj -> {
if (cls.isInstance(obj)) {
return Optional.of(f.apply((T) obj)); // As we must return a function taking an Object, we have to convert here
} else {
return Optional.empty();
}
};
}

以下示例演示了用法和行为:

    String s = "Hello World";
Integer i = 5;
Double d = 1.0 / 3;

Object x = s;
Object y = i;
Object z = d;

String res1 = caseType(x,
of(String.class, v -> v.substring(0, 5)),
of(Integer.class, v -> String.format("%d", v)),
of(Double.class, v -> String.format("%1.4f", v)));

String res2 = caseType(y,
of(String.class, v -> v.substring(0, 5)),
of(Integer.class, v -> String.format("%d", v)),
of(Double.class, v -> String.format("%1.4f", v)));

String res3 = caseType(z,
of(String.class, v -> v.substring(0, 5)),
of(Integer.class, v -> String.format("%d", v)),
of(Double.class, v -> String.format("%1.4f", v)));

String firstMatch = caseType(x,
of(String.class, v -> "first case"),
of(String.class, v -> "second case"));

String resNull = caseType(z,
of(String.class, v -> v.substring(0, 5)),
of(Integer.class, v -> String.format("%d", v)));

String resDefault = caseType(z,
of(String.class, v -> v.substring(0, 5)),
of(Integer.class, v -> String.format("%d", v)),
of(Object.class, v -> "unknown"));

String resSubtype1 = caseType(y,
of(Number.class, v -> String.format("%1.4f", v.doubleValue())),
of(Object.class, v -> "unknown"));

String resSubtype2 = caseType(z,
of(Number.class, v -> String.format("%1.4f", v.doubleValue())),
of(Object.class, v -> "unknown"));

System.out.println("res1: " + res1);
System.out.println("res2: " + res2);
System.out.println("res3: " + res3);
System.out.println("firstMatch: " + firstMatch);
System.out.println("resNull: " + resNull);
System.out.println("resDefault: " + resDefault);
System.out.println("resSubtype1: " + resSubtype1);
System.out.println("resSubtype2: " + resSubtype2);

输出:

res1:        Hello
res2: 5
res3: 0.3333
firstMatch: first case
resNull: null
resDefault: unknown
resSubtype1: 5.0000
resSubtype2: 0.3333

如果希望结果是 Optional (如果有匹配则有一个值,如果没有匹配则为空)可以相应地调整 case 函数:

private static <R> Optional<R> caseTypeNonNull(Object obj, Function<Object, Optional<R>>... functions) {
for (Function<Object, Optional<R>> f : functions) {
Optional<R> res = f.apply(obj);
if (res.isPresent()) {
return Optional.of(res.get());
}
}
return Optional.empty(); // Default case (no match)
}

关于java - 大小写类型(带返回值的开关),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51224109/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com