【发布时间】:2015-04-19 20:00:05
【问题描述】:
我阅读了有关 Lambda 表达式的 Java 8 教程,但不太了解“对特定类型的任意对象的实例方法的引用”的方法参考示例
在同一教程中,有一个示例“引用特定对象的实例方法”,看起来像。
public int compareByName(Person a, Person b) {
return a.getName().compareTo(b.getName());
}
Arrays.sort(rosterAsArray, myComparisonProvider::compareByName);
我可以看到这个工作,因为方法 compareByName 与 Comparator.compare 具有相同的签名,lambda (a, b) -> myComparisonProvider.compareByName(a, b) 接受两个参数并调用具有相同两个参数的方法。
现在“对特定类型的任意对象的实例方法的引用”示例使用 String::compareToIgnoreCase
String[] stringArray = { "Barbara", "James", "Mary", "John",
"Patricia", "Robert", "Michael", "Linda" };
Arrays.sort(stringArray, String::compareToIgnoreCase);
该方法的签名是int compareTo(String anotherString),与 Comparator.compare 不同。该教程不是很清楚,但似乎暗示您最终会得到一个 lambda,例如 (a, b) -> a.compareToIgnoreCase(b) 我不明白编译器如何决定 Arrays.sort 的第二个参数可接受的内容认为它可能足够聪明,可以理解如何调用该方法,所以我创建了一个示例。
public class LambdaTest {
public static void main(String... args) {
String[] stringArray = { "Barbara", "James", "Mary", "John", "Patricia", "Robert", "Michael", "Linda" };
Arrays.sort(stringArray, String::compareToIgnoreCase); // This works
// using Static methods
Arrays.sort(stringArray, FakeString::compare); // This compiles
Arrays.sort(stringArray, FakeString::compareToIgnoreCase); // This does not
// using Instance methods
LambdaTest lt = new LambdaTest();
FakeString2 fs2 = lt.new FakeString2();
Arrays.sort(stringArray, fs2::compare); // This compiles
Arrays.sort(stringArray, fs2::compareToIgnoreCase); // This does not
for(String name : stringArray){
System.out.println(name);
}
}
static class FakeString {
public static int compareToIgnoreCase(String a) {
return 0;
}
public static int compare(String a, String b) {
return String.CASE_INSENSITIVE_ORDER.compare(a, b);
}
}
class FakeString2 implements Comparator<String> {
public int compareToIgnoreCase(String a) {
return 0;
}
@Override
public int compare(String a, String b) {
return String.CASE_INSENSITIVE_ORDER.compare(a, b);
}
}
}
有人能解释一下为什么上述两个 Arrays.sort 即使使用与 String.compareToIgnoreCase 方法相同的方法也无法编译
【问题讨论】: