Java 实例方法引用和Lambda参数

Java 实例方法引用和Lambda参数,java,lambda,java-8,closures,method-reference,Java,Lambda,Java 8,Closures,Method Reference,我很难理解方法引用的语法,其中有两个参数a和b,并且引用的是b上的a方法 例如,我了解如何 Arrays.sort(personArray, comparators::compareByName); 相当于 Arrays.sort(personArray, (o1, o2) -> comparators.compareByName(o1, o2)); 因为在这种情况下,lambda参数匹配方法调用参数(o1,o2) 但是对于这个兰姆达 stream.sorted((o1, o2) -&

我很难理解方法引用的语法,其中有两个参数
a
b
,并且引用的是
b
上的
a
方法

例如,我了解如何

Arrays.sort(personArray, comparators::compareByName);
相当于

Arrays.sort(personArray, (o1, o2) -> comparators.compareByName(o1, o2));
因为在这种情况下,lambda参数匹配方法调用参数
(o1,o2)

但是对于这个兰姆达

stream.sorted((o1, o2) -> o1.compareToIgnoreCase(o2));
我的IDE告诉我这相当于:

stream.sorted(String::compareToIgnoreCase);
我并没有找到一条规则来替换这种语法:
a.method(b)
,而是使用方法引用


例如,如果lambda有三个或更多参数,该怎么办?这合法吗?第一个参数是否成为方法目标,其余参数是否成为参数?

我想您正在寻找,其中包括:

如果表单是
ReferenceType::[TypeArguments]Identifier
,则调用方法的主体类似地具有编译时声明的方法调用表达式的效果,该声明是方法引用表达式的编译时声明。方法调用表达式的运行时评估如§15.12.4.3、§15.12.4.4和§15.12.4.5所述,其中:

  • 调用模式源自§15.12.3中规定的编译时声明

  • 如果编译时声明是实例方法,那么目标引用是调用方法的第一个形式参数。否则,就没有目标引用

  • 如果编译时声明是实例方法,那么方法调用表达式(如果有)的参数是调用方法的第二个和后续形式参数。否则,方法调用表达式的参数就是调用方法的形式参数

基本上,请注意最后两个项目

例如,如果lambda有三个或更多参数,该怎么办?这合法吗?第一个参数是否成为方法目标,其余参数是否成为方法目标


是的:)

对于那些觉得Oracle文档有点难以理解的人,我想在这里举几个例子。 假设您需要对比较器实例的引用:

.sorted(String::compareTo)
String::compareTo与以下内容相同:

(String a, String b) -> a.compareTo(b);
因为,正如Jon所解释的,一个方法引用将被转换为一个lambda,该lambda需要2个参数。作为第一个参数传入流中的实际任意对象,以及另外一个参数(因为Comparator期望
int compare(to1,t2)
)。 另一种情况:

.map(Employee::getSalary)
在这种情况下,map需要:函数。函数需要实现
R apply(T var1)
-一个带有1个参数的方法。在这种情况下,将传递给lambda的唯一参数是Employee上的实际任意对象实例

总之,根据编译时上下文,对任意对象的方法引用将始终“转换”为lambda,该lambda期望该对象作为第一个参数+目标方法以相同的对应顺序需要的任意数量的参数。

请参阅