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

Maj*_*imi 14 java lambda java-8

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

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

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

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

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

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

ajb*_*ajb 19

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

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

(a, b, c) -> SomeClass.func(a, b, c);
Run Code Online (Sandbox Code Playgroud)

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

(a, b, c) -> a.func(b, c);
Run Code Online (Sandbox Code Playgroud)

哪里a有类型SomeClass.

编辑: Sotirios的回答演示了一种不同类型的方法引用:example::methodwhere example是引用变量(而不是类名).这意味着同样的

(a, b) -> example.method(a, b);
Run Code Online (Sandbox Code Playgroud)

或者更确切地说

(a, b) -> __someFinalTemporary.method(a, b);
Run Code Online (Sandbox Code Playgroud)

在评估方法引用的位置__someFinalTemporary指定example的位置,以便example稍后更改时,仍使用之前的值调用该方法example.

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


Sot*_*lis 8

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

public class Example {  
    public static void main(String[] args) throws Exception {
        List<String> strings = new ArrayList<String>();
        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<String> l) -> {
            example.method(s, l);
        };
        lambda.funct("another string", strings);
        System.out.println("List now contains: " + strings);
    }

    interface Functional {
        void funct(String value, List<String> list);
    }

    void method(String value, List<String> toAddTo) {
        System.out.println("adding");
        toAddTo.add(value);
    }
}
Run Code Online (Sandbox Code Playgroud)

它打印

adding
List now contains: [a string]
adding
List now contains: [a string, another string]
Run Code Online (Sandbox Code Playgroud)

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


Lou*_*man 5

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

对,那是正确的.


Tao*_*ang 5

根据 Joshua Bloch 在他的《Effective Java》(第 3 版)中的说法,有 5 种类型的方法引用用例。

在此输入图像描述