简体   繁体   中英

Passing Java Generic Lambda Parameter Into Method Local Invocation

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?

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.

The problem with your code in this line public static Long otherMethod(Function<String, Long> otherParam)

You are calling non generic method form generic method, because of this eventually you have to cast your parameter which is not good thing to avoid exceptions while running your code

try below code

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

    public static <T, U> U otherMethod(Function<T, U> otherParam,T value) {
        return otherParam.apply(value);
    }

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM