Passing Java Generic Lambda Parameter Into Method Local Invocation

marcius.tan :

Here, I am trying to pass lambda argument into local invocation of a method that accepts lambda argument:

package Desktop;

import java.util.function.*;

public class MyClass {

    public static <T, U> U myMethod(Function<T, U> myParam) {
        return otherMethod(myParam);
    }

    public static Long otherMethod(Function<String, Long> otherParam) {
        return otherParam.accept("900");
    }

    public static void main(String[] args) {
        System.out.println(myMethod(Long::valueOf));
    }
}

I browsed for some help on sites and it shows that we can pass lambda (with generics) from one parameter into another:

public static <T, G> List<G> fromArrayToList(T[] a, Function<T, G> mapperFunction) {
    return Arrays.stream(a).map(mapperFunction).collect(Collectors.toList());
}

/*
    Signature for map() is like this:
    <R> Stream<R> map(Function<? super T, ? extends R> mapper)
*/

Now how to properly pass a lambda with generics from parameter method into another?

Michael :

One problem is that there are two signatures of valueOf. One takes a primitive long, the other takes a string.

There is no way for Java to know which one you mean.

You can manually specify by using a type witness:

System.out.println(MyClass.<String, Long>myMethod(Long::valueOf));

or, if you prefer, assign the method reference to a variable so that additional type information can be inferred from the variable.

Function<String, Long> func = FakeLong::valueOf;
System.out.println(MyClass.myMethod(func));

Another problem is here:

return otherMethod(myParam);

Fact is, otherMethod specifically requires a function that takes a String and returns a long, while myParam can be any function at all. There is a fundamental incompatibility here. Your design is wrong.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=422971&siteId=1