Java Lambda 表达式
Java Lambda Expression
我目前正在 JDK 1.8 学习 lambda 表达式。我遇到了一些我发现我不理解的代码。
代码如下:
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")
。
我的理解是编译器需要找到一个与
具有相同签名的静态方法
public <T extends Comparable<T>> int compare(T obj1, T obj2 );
我已经创建了这样一个方法并且它有效。我不明白为什么 java 编译器调用 "5".compareTo("2")
。他们的方法签名不一样
关于编译器为何生成此类代码的任何信息?
如果您正在尝试学习方法参考,您应该求助于某种学习方式 material,例如Oracle’s Java tutorial。你会发现:
Kinds of method references
Kind
Example
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
个方法。
您的方法引用 Comparable::<String>compareTo
匹配“对特定类型的任意对象的实例方法的引用”类型。
此时值得注意的是,您实际上是在引用方法 Comparable.compareTo
,就好像您已经编写了 Comparable::compareTo
。由于引用的方法本身没有类型参数,因此您的类型参数无效。例如。你可以写 Comparable::<Button>compareTo
得到相同的结果。
引用的方法具有函数签名 (Comparable,Comparable) → int
,因为它在一个 Comparable
上调用 Comparable.compareTo
时消耗两个 Comparable
,传递第二个 Comparable
作为参数(它将 return 和 int
)。这与您的 interface
的功能签名相匹配
interface MyComparable {
public <T extends Comparable<T>> int compare(T obj1, T obj2 );
}
因此可以在此上下文中使用方法参考。
我简化了功能签名;实际上它们是 (T,T)→int
使用 <T extends Comparable<T>>
,因此您只能使用此函数比较 相同 具体 Comparable
实现的两个实例。
所以您想知道如何将签名与预期不同的方法引用作为 lambda 表达式发送。但它们不需要完全相同。基本上,只有 参数列表 和 return 类型 很重要:
A lambda expression can be assigned to a target type T if all of the following conditions hold:
T is a functional interface type
The lambda expression has the same number of parameters as T's method, and those parameters' types are the same
Each expression returned by the lambda body is compatible with T's method's return type
Each exception thrown by the lambda body is allowed by T's method's throws clause
您的 compare()
(String
, String
) 的参数列表可以与 String#compareTo()
(this
, String
) 和它们的 return 类型也是相同的 (int
),因此当需要另一个时,一个可以用作 lambda。
我目前正在 JDK 1.8 学习 lambda 表达式。我遇到了一些我发现我不理解的代码。
代码如下:
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")
。
我的理解是编译器需要找到一个与
public <T extends Comparable<T>> int compare(T obj1, T obj2 );
我已经创建了这样一个方法并且它有效。我不明白为什么 java 编译器调用 "5".compareTo("2")
。他们的方法签名不一样
关于编译器为何生成此类代码的任何信息?
如果您正在尝试学习方法参考,您应该求助于某种学习方式 material,例如Oracle’s Java tutorial。你会发现:
Kinds of method references
Kind Example 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
个方法。
您的方法引用 Comparable::<String>compareTo
匹配“对特定类型的任意对象的实例方法的引用”类型。
此时值得注意的是,您实际上是在引用方法 Comparable.compareTo
,就好像您已经编写了 Comparable::compareTo
。由于引用的方法本身没有类型参数,因此您的类型参数无效。例如。你可以写 Comparable::<Button>compareTo
得到相同的结果。
引用的方法具有函数签名 (Comparable,Comparable) → int
,因为它在一个 Comparable
上调用 Comparable.compareTo
时消耗两个 Comparable
,传递第二个 Comparable
作为参数(它将 return 和 int
)。这与您的 interface
interface MyComparable {
public <T extends Comparable<T>> int compare(T obj1, T obj2 );
}
因此可以在此上下文中使用方法参考。
我简化了功能签名;实际上它们是 (T,T)→int
使用 <T extends Comparable<T>>
,因此您只能使用此函数比较 相同 具体 Comparable
实现的两个实例。
所以您想知道如何将签名与预期不同的方法引用作为 lambda 表达式发送。但它们不需要完全相同。基本上,只有 参数列表 和 return 类型 很重要:
A lambda expression can be assigned to a target type T if all of the following conditions hold:
T is a functional interface type
The lambda expression has the same number of parameters as T's method, and those parameters' types are the same
Each expression returned by the lambda body is compatible with T's method's return type
Each exception thrown by the lambda body is allowed by T's method's throws clause
您的 compare()
(String
, String
) 的参数列表可以与 String#compareTo()
(this
, String
) 和它们的 return 类型也是相同的 (int
),因此当需要另一个时,一个可以用作 lambda。