使用方法引用而不是多参数lambda

我对“引用特定类型的任意对象的实例方法”背后的概念感到困惑。 Oracle 文档有一个关于此的示例:

String[] stringArray = { "Barbara", "James", "Mary", "John", "Patricia", "Robert", "Michael", "Linda" }; Arrays.sort(stringArray, String::compareToIgnoreCase); 

我在这种方法参考中看到的大多数例子都是这样的:如果lambda类似于: x -> x.func()那么你可以像ClassOfX::func一样编写它。 文档中的示例说:

方法引用String :: compareToIgnoreCase的等效lambda表达式将具有forms参数列表(String a,String b),其中a和b是用于更好地描述此示例的任意名称。 方法引用将调用方法a.compareToIgnoreCase(b)。

问题是:对于任何两个参数lambda,如(a, b) -> a.func(b)func方法必须是第一个参数的实例方法,lambda的第二个参数将作为参数传递给该方法吗? 如果我们有多个参数lambda,那么func方法必须是lambda的第一个参数的实例方法,而lambda的其他参数将按照lambda中出现的顺序传递给func ? 我的意思是代替(a, b, c) -> a.func(b, c)我们可以编写ClassOfA::func

对不起我的英语。 我希望我能清楚地解决这个问题。

SomeClass::func可能意味着两件事,具体取决于func是静态方法还是实例方法。

(1)如果func是静态方法,那么SomeClass::func是一个lambda, SomeClass::func传递方法的所有参数:

 (a, b, c) -> SomeClass.func(a, b, c); 

(2)如果func是一个实例方法,那么SomeClass::func是一个lambda,它使用第一个参数作为实例,如你所愿:

 (a, b, c) -> a.func(b, c); 

其中a类型为SomeClass

编辑: Sotirios的答案演示了一种不同类型的方法引用: example::method其中example是一个引用变量(而不是类名)。 这意味着同样的

 (a, b) -> example.method(a, b); 

或者更确切地说

 (a, b) -> __someFinalTemporary.method(a, b); 

其中__someFinalTemporary在评估方法引用的位置分配给example ,因此如果稍后更改example ,则仍使用example的较早值调用该方法。

[第四种是SomeClass::new ,它将参数传递给构造函数。 我认为这就是全部。]

这是一个演示实例方法引用行为的小例子。

 public class Example { public static void main(String[] args) throws Exception { List strings = new ArrayList(); Example example = new Example(); Functional methodRef = example::method; methodRef.funct("a string", strings); System.out.println("List now contains: " + strings); Functional lambda = (String s, List l) -> { example.method(s, l); }; lambda.funct("another string", strings); System.out.println("List now contains: " + strings); } interface Functional { void funct(String value, List list); } void method(String value, List toAddTo) { System.out.println("adding"); toAddTo.add(value); } } 

它打印

 adding List now contains: [a string] adding List now contains: [a string, another string] 

这两者或多或少是等价的。 在lambda的情况下,调用方法的变量需要有效地final

我的意思是代替(a,b,c) – > a.func(b,c)我们可以编写ClassOfA :: func

对,那是正确的。