Lambda Expression and generic method

java lambda generic return type
what is a lambda expression
when to use lambda expressions
target method is generic
lambda expression java
java generics
lambdas
java functional interface

Suppose I've a generic interface:

interface MyComparable<T extends Comparable<T>>  {
    public int compare(T obj1, T obj2);
}

And a method sort:

public static <T extends Comparable<T>> 
       void sort(List<T> list, MyComparable<T> comp) {
    // sort the list
}

I can invoke this method and pass a lambda expression as argument:

List<String> list = Arrays.asList("a", "b", "c");
sort(list, (a, b) -> a.compareTo(b));

That will work fine.

But now if I make the interface non-generic, and the method generic:

interface MyComparable {
    public <T extends Comparable<T>> int compare(T obj1, T obj2);
}

public static <T extends Comparable<T>> 
       void sort(List<T> list, MyComparable comp) {
}

And then invoke this like:

List<String> list = Arrays.asList("a", "b", "c");
sort(list, (a, b) -> a.compareTo(b));

It doesn't compile. It shows error at lambda expression saying:

"Target method is generic"

OK, when I compiled it using javac, it shows following error:

SO.java:20: error: incompatible types: cannot infer type-variable(s) T#1
        sort(list, (a, b) -> a.compareTo(b));
            ^
    (argument mismatch; invalid functional descriptor for lambda expression
      method <T#2>(T#2,T#2)int in interface MyComparable is generic)
  where T#1,T#2 are type-variables:
    T#1 extends Comparable<T#1> declared in method <T#1>sort(List<T#1>,MyComparable)
    T#2 extends Comparable<T#2> declared in method <T#2>compare(T#2,T#2)
1 error

From this error message, it seems like compiler is not able to infer the type arguments. Is that the case? If yes, then why is it happening like this?

I tried various ways, searched through the internet. Then I found this JavaCodeGeeks article, which shows a way, so I tried:

sort(list, <T extends Comparable<T>>(a, b) -> a.compareTo(b));

which again doesn't work, contrary to what that article claims that it works. Might be possible that it used to work in some initial builds.

So my question is: Is there any way to create lambda expression for a generic method? I can do this using a method reference though, by creating a method:

public static <T extends Comparable<T>> int compare(T obj1, T obj2) {
    return obj1.compareTo(obj2);
}

in some class say SO, and pass it as:

sort(list, SO::compare);

Lambda Expression and generic method, Generally, lambdas work well with generic types. When you implement such a method, the constructor expression is an IntFunction<T[]>,  Lambda(Expression, String, IEnumerable<ParameterExpression>) Creates a LambdaExpression by first constructing a delegate type from the expression body, the name for the lambda, and an enumerable collection of parameter expressions. It can be used when the delegate type is not known at compile time. Lambda(Expression, Boolean, ParameterExpression[])

Using method reference, i found other way to pass the argument:

List<String> list = Arrays.asList("a", "b", "c");        
sort(list, Comparable::<String>compareTo);

3.9. Lambdas and Generics, The following code creates a lambda expression by using the generic Arrays.​asList method and sets the parameter as String. import java.util.Arrays; import  Since the purpose of the question is to use a lambda expression, here is a solution. It takes a different route by using weak typing instead of the proposed strong typing, but accomplishes the same thing nonetheless.

You mean something like this?:

<T,S>(T t, S s)->...

Of what type is this lambda? You couldn't express that in Java and therefore cannot compose this expression in a function application and expressions have to be composable.

For this need to be work you would need support for Rank2 Types in Java.

Methods are allowed to be generic but therefore you couldn't use them as expressions. They can, however be reduced to lambda expression by specializing all necessary generic types before you can pass them: ClassName::<TypeName>methodName

Lambda Expressions (The Java™ Tutorials > Learning the Java , that along with generics and Lambda Expression enables us to write is able to infer the type parameter to the following generic method: ? Lambda expression is a shorter way of representing anonymous methods. A lambda expression uses =>, the lambda declaration operator, to separate the lambda's parameter list from its executable code. To create a lambda expression, you specify input parameters (if any) on the left side of the lambda operator, and you put the expression or statement block on the other side.

Just point compiler the proper version of generic Comparator with (Comparator<String>)

So the answer will be

sort(list, (Comparator<String>)(a, b) -> a.compareTo(b));

Java Lambda - Java Generic Method Reference, Suppose I ve a generic interface: interface MyComparable<T extends Comparable<T>> { public int compare(T obj1, T obj2); }. And a method sort: public static <T  In C#3.0 Lambda expressions are introduced. It provides a simple, more concise, functional syntax to write anonymous methods. The word lambda is taken from the lambda calculus, where everything is expressed in terms of functions. A lambda expression is written as a parameter list, followed by the => (termed as “goes into”) symbol,

Generalized Target-Type Inference in Java, The method references are introduced in Java 8 similar to lambda expression. It can allow us to reference methods or constructors without  To create a lambda expression, you specify input parameters (if any) on the left side of the lambda operator and an expression or a statement block on the other side. Any lambda expression can be converted to a delegate type. The delegate type to which a lambda expression can be converted is defined by the types of its parameters and return value.

Java - Lambda Expression and generic method, Conceptually, a generic lambda is equivalent to a function object with a templatized function-call operator method: struct LambdaClosureType { Tip: Lambda expressions use the token => in an expression context. In this context, the token is not a comparison operator. Goes to: The => operator can be read as "goes to.". It is always used when declaring a lambda expression. Invoke: With Invoke, a method on Func and Action, we execute the methods in the lambdas.

How to use method references with Generics in Java?, Lambda expression is, essentially, an anonymous or unnamed method. The lambda expression does not execute on its own. Instead, it is used to implement a method defined by a functional interface. How to define lambda expression in Java?

Comments
  • However, this restriction does not apply to method references to generic methods. You can use a method reference to a generic method with a generic functional interface.
  • I'm sure there's a good reason for this restriction. What is it?
  • @Sandro: there is simply no syntax for declaring type parameters for a lambda expression. And such a syntax would be very complicated. Keep in mind that the parser still must be able to tell such a lambda expression with type parameters apart from other legal Java constructs. Thus you have to resort to method references. The target method can declare type parameters using an established syntax.
  • @Holger still, where type parameters can be auto-deduced, the compiler could decude a capure type as it does when you declare e.g. Set<?> and do type-checks with those captured types. Sure, that makes it impossible to give them as type-parameters in the body, but if you'd need that, resorting to method references is a good alternative
  • "Of what type is this lambda? You couldn't express that in Java..." The type would be inferred using the context, just as with any other lambda. The type of a lambda isn't explicitly expressed in the lambda itself.
  • incompatible types: java.util.Comparator<java.lang.String> cannot be converted to MyComparable and MyComparable is not generic (no type) so (MyComparable<String>) would not work either
  • Dont know how you are typing the code @CarlosHeuberger, but it works for me very well, this is what i was looking for.
  • @IvanPeralesM. after 2 months... I copied&pasted your code and copied&pasted above line over your sort line - just that, like here: ideone.com/YNwBbF ! Are you sure you did type above code exactly? using Compartor ?
  • No i dont, i use the idea behind the answer, to cast the functional to tell the compile what type it is and it worked.
  • @IvanPeralesM. well, then what is your problem with my "typing"? The answer, as it is posted, does not work.