Java Lambda表达式与泛型方法

Java Lambda表达式与泛型方法,java,generics,lambda,java-8,Java,Generics,Lambda,Java 8,假设我有一个通用接口: interface MyComparable<T extends Comparable<T>> { public int compare(T obj1, T obj2); } 我可以调用此方法并将lambda表达式作为参数传递: List<String> list = Arrays.asList("a", "b", "c"); sort(list, (a, b) -> a.compareTo(b)); List<

假设我有一个通用接口:

interface MyComparable<T extends Comparable<T>>  {
    public int compare(T obj1, T obj2);
}
我可以调用此方法并将lambda表达式作为参数传递:

List<String> list = Arrays.asList("a", "b", "c");
sort(list, (a, b) -> a.compareTo(b));
List<String> list = Arrays.asList("a", "b", "c");        
sort(list, Comparable::<String>compareTo);
从这个错误消息中,编译器似乎无法推断类型参数。是这样吗?如果是的话,为什么会这样

我尝试了各种方法,通过互联网搜索。然后我发现,这说明了一种方法,所以我试着:

sort(list, <T extends Comparable<T>>(a, b) -> a.compareTo(b));
如果函数接口中的方法具有类型参数,则不能对函数接口使用lambda表达式。见:

如果T是函数接口类型(§9.8),且表达式与函数类型[..]T一致,则lambda表达式与目标类型T兼容[..] 正确:

  • 函数类型没有类型参数
  • [……]

使用方法引用,我找到了传递参数的其他方法:

List<String> list = Arrays.asList("a", "b", "c");
sort(list, (a, b) -> a.compareTo(b));
List<String> list = Arrays.asList("a", "b", "c");        
sort(list, Comparable::<String>compareTo);
List List=Arrays.asList(“a”、“b”、“c”);
排序(列表,可比::比较);

你的意思是这样的吗

<T,S>(T t, S s)->...
(T T,S)->。。。
这个兰姆达是什么类型的?您无法在Java中表达这一点,因此无法在函数应用程序中组合此表达式,并且表达式必须是可组合的

对于这项需要的工作,您需要Java中的支持


方法允许是泛型的,但因此不能将它们用作表达式。但是,通过在传递它们之前专门化所有必需的泛型类型,可以将它们简化为lambda表达式:
ClassName::methodName

只需使用
(比较器)

所以答案是


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

但是,此限制不适用于泛型方法的方法引用。您可以使用方法引用来引用具有泛型函数接口的泛型方法。我相信这一限制是有充分理由的。这是什么?@Sandro:根本没有为lambda表达式声明类型参数的语法。这样的语法会非常复杂。请记住,解析器仍然必须能够区分具有类型参数的lambda表达式与其他合法Java构造。因此,您必须求助于方法引用。目标方法可以使用已建立的语法声明类型参数。@Holger尽管如此,在类型参数可以自动推导的情况下,编译器可以像您声明(例如,设置并使用这些捕获的类型进行类型检查)时那样声明capure类型。当然,这使得不可能在主体中将它们作为类型参数提供,但是如果需要的话,求助于方法引用是一个很好的选择
不兼容的类型:java.util.Comparator不能转换为MyComparable
MyComparable
不是泛型(无类型),因此
(MyComparable)
不起作用。我不知道您是如何键入代码的@CarlosHeuberger,但它对我很有效,这就是我一直在寻找的。@IvanPeralesM。两个月后。。。我复制并粘贴了您的代码,并将代码复制并粘贴到排序行上方的行上-就像这里:!你确定你准确地输入了上面的代码吗?使用
比较器
?不,我没有,我使用答案背后的想法来转换函数,告诉编译器它是什么类型,它工作了。@IvanPeralesM。那你对我的“打字”有什么问题?正如所发布的那样,答案不起作用。
“这个lambda是什么类型的?您无法在Java中表达它…”
该类型将使用上下文进行推断,就像使用任何其他lambda一样。lambda的类型没有在lambda本身中显式表示。
public static <T extends Comparable<T>> int compare(T obj1, T obj2) {
    return obj1.compareTo(obj2);
}
sort(list, SO::compare);
List<String> list = Arrays.asList("a", "b", "c");        
sort(list, Comparable::<String>compareTo);
<T,S>(T t, S s)->...