Java 8 extends the functional interface and integrates them

I have a functional interface that extends the standard jdk function to simple types. Now I want to combine the two functions using andThen, which throws a compiler error

Error: (25, 25) java: the andThen method in the java.util.function.Function<T,R> interface cannot be applied to the specified types; required: java.util.function.Function<? super ui.instrumentation.api.messaging.Message<R>,? extends V> java.util.function.Function<? super ui.instrumentation.api.messaging.Message<R>,? extends V> java.util.function.Function<? super ui.instrumentation.api.messaging.Message<R>,? extends V> found: ui.instrumentation.api.transformation.Transformer<T,R> reason: cannot call variables of type V (mismatch of arguments; ui.instrumentation.api.transformation.Transformer<T,R> cannot be converted to java.util.function.Function<? super ui.instrumentation.api.messaging.Message<R>,? extends V> )

Here is a sample code:

 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)); } } 

Is there a way to combine functions that extend the standard functional interface, or is there a better way to do this?

+6
source share
2 answers

You need both to fix your generics, and instead of andThen , which will return only Function , you better invest lambda yourself:

 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)); } 
+5
source

The first problem is that andThen takes the return value of one function and makes the parameter type of the next function, so you need, as @LouisWasserman explains, combine them at the end with the output type, one of which corresponds to the input type of the following:

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

The second problem, he explains, is that Function.andThen , which you call, returns Function , not Transformer . Please note, however, that Function and Transformer have the same shape - one input, one output. Because of this, you can use one and then adapt it to another using a method reference as follows:

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

You do not need to create a function for this. You can use the same method calling Function.andThen() directly:

  Transformer<String,Integer> t1 = ... Transformer<Integer,Double> t2 = ... Transformer<Double,String> t3 = ... Transformer<String,String> t123 = t1.andThen(t2).andThen(t3)::apply; 
+5
source

All Articles