Java 8扩展功能接口并将它们组合在一起

时间:2016-05-03 23:02:32

标签: java lambda functional-programming java-8

我有一个功能接口,它将标准的jdk函数扩展为泛型类型。现在我想使用andThen组合两个函数,这就是抛出编译器错误

  

错误:(25,25)java:方法然后在界面中   java.util.function.Function<T,R>无法应用于给定类型;
  必填:java.util.function.Function<? super ui.instrumentation.api.messaging.Message<R>,? extends V>发现:   ui.instrumentation.api.transformation.Transformer<T,R>原因:   不能推断出类型变量V.       (参数不匹配; ui.instrumentation.api.transformation.Transformer<T,R>不能   转换为java.util.function.Function<? super ui.instrumentation.api.messaging.Message<R>,? extends V>

以下是示例代码:

public interface Transformer<T,R> extends Function<Message<T>, Message<R>> {

    static <T, R> Transformer<T, R> combine2(Transformer<T, R> first, Transformer<T, R> second) {
        return first.andThen(second));
    } 
}

有没有办法组合扩展标准Function接口的函数,或者有更好的方法吗?

2 个答案:

答案 0 :(得分:5)

你需要修复你的泛型,而不是使用只返回Function的{​​{1}},你最好自己内联lambda:

static <T1, T2, T3> Transformer<T1, T3> combine2(Transformer<T1, T2> first, Transformer<T2, T3> second) {
    return (Message<T1> input) -> second.apply(first.apply(input));
} 

答案 1 :(得分:5)

第一个问题是andThen获取一个函数的返回值并使其成为下一个函数的参数类型,因此,正如@LouisWasserman解释的那样,您需要将它们端到端地链接到输出类型为1与下一个的输入类型匹配:

static <T1, T2, T3> Transformer<T1, T3> combine2(Transformer<T1, T2> first, Transformer<T2, T3> second) {

正如他所解释的那样,第二个问题是,您呼叫的Function.andThen会返回Function,而不是Transformer。但请注意,FunctionTransformer具有相同的形状 - 单输入,单输出。因此,您可以使用一个,然后使用如下方法引用将其调整到另一个:

static <T1, T2, T3> Transformer<T1, T3> combine(Transformer<T1, T2> first, Transformer<T2, T3> second) {
    return first.andThen(second)::apply;
}

您不需要创建执行此操作的功能。您可以使用相同的技术直接调用Function.andThen()

    Transformer<String,Integer> t1 = ...
    Transformer<Integer,Double> t2 = ...
    Transformer<Double,String> t3 = ...

    Transformer<String,String> t123 = t1.andThen(t2).andThen(t3)::apply;