如何为返回带泛型的函数的方法声明泛型

时间:2018-01-16 13:54:34

标签: java generics functional-programming pattern-matching

我正在尝试在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>这样的返回类型才能拥有...我不知道该怎么做。

那么如何为返回带有泛型的函数的方法声明泛型?

2 个答案:

答案 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