Java Lambda表达式 [英] Java Lambda Expression
问题描述
我目前正在JDK 1.8上学习lambda表达式。我遇到了一些我发现我不理解的代码。
I am currently learning lambda expressions on JDK 1.8. I have come across some code I have found that I do not understand.
这是代码:
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.lang.Comparable;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args ) throws Exception
{
List<String> list = Arrays.asList("a", "b", "c");
sort(list, Comparable::<String>compareTo);
}
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) {
int n = comp.compare("5","2");
System.out.println(n);
}
}
comp .compare(5,3)
最终执行5.compareTo(2)
。
我的理解是编译器需要找到一个具有相同签名的静态方法
comp.compare("5", "3")
eventually executes "5".compareTo("2")
.
My understanding was the compiler needs to find a static method with same signature as
public <T extends Comparable<T>> int compare(T obj1, T obj2 );
我已经创建了这样一个方法,但它确实有效。我不明白为什么java编译器调用5.compareTo(2)
。他们的方法签名不一样。
I have created such a method and it works. I do not understand why the java compiler calls "5".compareTo("2")
. Their method signitures are not the same.
关于编译器为什么生成这种代码的任何信息?
Any information as to why the compiler generates this kind of code?
推荐答案
如果您正在尝试学习方法参考,您应该使用某种学习材料,例如: Oracle的Java教程。在那里你找到:
If you are trying to learn method references, you should resort to some sort of learning material, e.g. Oracle’s Java tutorial. There you find:
各种方法参考
种类例子
Kinds of method references
Kind Example
- 对静态方法的引用
ContainingClass :: staticMethodName
- 引用特定对象的实例方法
containsObject :: instanceMethodName
- 引用任意对象的实例方法特殊类型
ContainingType :: methodName
- 对构造函数的引用
ClassName :: new
- Reference to a static method
ContainingClass::staticMethodName
- Reference to an instance method of a particular object
containingObject::instanceMethodName
- Reference to an instance method of an arbitrary object of a particular type
ContainingType::methodName
- Reference to a constructor
ClassName::new
所以你看,方法引用不限于 static
methods。
So you see, method references are not restricted to static
methods.
您的方法参考 Comparable ::< String> compareTo
匹配类型引用ar的实例方法特定类型的比特对象。
Your method reference Comparable::<String>compareTo
matches the kind "Reference to an instance method of an arbitrary object of a particular type".
此时值得注意的是,您实际上是在引用方法 Comparable.compareTo
好像你写了 Comparable :: compareTo
。由于引用的方法本身没有类型参数,因此类型参数无效。例如。你可以用相同的结果写 Comparable ::< Button> compareTo
。
At this point it’s worth noting that you are actually referencing the method Comparable.compareTo
as if you had written Comparable::compareTo
. Since the referenced method has no type parameters on its own, your type argument has no effect. E.g. you could write Comparable::<Button>compareTo
with the same result.
引用的方法具有功能签名(可比较,可比较)→int
因为它在调用 Comparable时消耗两个
在一个 Comparable
。 compareTo Comparable
上,将第二个 Comparable
作为参数传递(它将返回一个 INT
)。这匹配界面的功能签名
The referenced method has the functional signature (Comparable,Comparable) → int
as it consumes two Comparable
s when invoking Comparable.compareTo
on one Comparable
, passing the second Comparable
as argument (and it will return an int
). This matches the functional signature of your interface
interface MyComparable {
public <T extends Comparable<T>> int compare(T obj1, T obj2 );
}
因此可以在此上下文中使用方法参考。
so the method reference can be used in this context.
我简化了功能签名;实际上它们是(T,T)→int
使用< T extends Comparable< T>>
,因此你只能使用此函数比较相同具体 Comparable
实现的两个实例。
I have simplified the functional signatures; actually they are (T,T)→int
using <T extends Comparable<T>>
, therefore you can only compare two instances of the same concrete Comparable
implementation using this function.
这篇关于Java Lambda表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!