我正在尝试在java中使用某种模式匹配,所以我想出了这个方法:
public Function<SimpleEntry<T, R>[], R> matchWith(T match){
return functions -> Stream.of(functions)
.filter(entry -> entry.getKey().equals(match))
.findFirst()
.map(Entry::getValue)
.orElse(null);
}
这显然不起作用,我找不到相关的问题。
想法是使用这样的方法:
final String value = matchWith(Type.B).apply(
new SimpleEntry<>(Type.A, "Type A matches"),
new SimpleEntry<>(Type.B, "Type B matches")
)
注意:我可能需要声明像Function<Pair<T, R>..., R>
这样的返回类型才能拥有...我不知道该怎么做。
那么如何为返回带有泛型的函数的方法声明泛型?
答案 0 :(得分:1)
您必须提供自己的功能界面:
@FunctionalInterface
interface Matcher<T, R> {
R apply(Entry<T, R>...entries);
}
private static <T, R> Matcher<T, R> matchWith(T match) {
return functions -> Stream.of(functions)
.filter(entry -> entry.getKey().equals(match))
.findFirst()
.map(Entry::getValue)
.orElse(null);
}
final String value = EnclosingClass.<Type, String>matchWith(Type.B).apply(
new SimpleEntry<>(Type.A, "Type A matches"), // could also use Map.entry in Java 9
new SimpleEntry<>(Type.B, "Type B matches")
);
此外,类型推断看起来不够智能,无法确定它应该返回Matcher<Type, String>
,因此您必须手动提供类型参数(就像我上面所做的那样{{1}是声明EnclosingClass
)的类。
可以说更好的方法是直接将条目列表传递给matchWith
,然后你不需要界面,它也能够自动计算出正确的返回类型:
matchWith
private static <T, R> R matchWith(T match, Entry<T, R>...enries) {
return Stream.of(enries)
.filter(entry -> entry.getKey().equals(match))
.findFirst()
.map(Entry::getValue)
.orElse(null);
}
作为一个有趣的事实,您以后尝试创建的某些类似功能可能会在以后添加到String value = matchWith(Type.B,
new SimpleEntry<>(Type.A, "Type A matches"),
new SimpleEntry<>(Type.B, "Type B matches")
);
语句中:JEP draft: Switch Expressions for the Java Language
答案 1 :(得分:1)
不仅可以使用函数式编程,还可以使用Target Types为方法参数和返回类型定义泛型。
public <T, R> Function<Pair<T, R>[], R> matchWith(T match) {}
参考:https://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html