Java 使用方法引用代替多参数lambda

Java 使用方法引用代替多参数lambda,java,lambda,java-8,Java,Lambda,Java 8,我对“引用特定类型的任意对象的实例方法”背后的概念感到困惑。Oracle有这样一个例子: String[] stringArray = { "Barbara", "James", "Mary", "John", "Patricia", "Robert", "Michael", "Linda" }; Arrays.sort(stringArray, String::compareToIgnoreCase); 我看到的这种方法引用的大多数示例都是这样的:如果lambda类似于:x->x.func(

我对“引用特定类型的任意对象的实例方法”背后的概念感到困惑。Oracle有这样一个例子:

String[] stringArray = { "Barbara", "James", "Mary", "John", "Patricia", "Robert", "Michael", "Linda" };
Arrays.sort(stringArray, String::compareToIgnoreCase);
我看到的这种方法引用的大多数示例都是这样的:如果lambda类似于:
x->x.func()
,那么您可以像
ClassOfX::func
那样编写它。文档中的示例说明:

方法引用的等效lambda表达式 String::compareToIgnoreCase将具有正式的参数列表 (字符串a,字符串b),其中a和b是用于更好地使用的任意名称 请描述这个例子。方法引用将调用该方法 a、 比较IgnoreCase(b)

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

我为我的英语感到抱歉。我希望我把问题说清楚了

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


是的,这是正确的。

下面是一个演示实例方法引用行为的小示例

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);
    }
}

这两者大致相当。在lambda的情况下,调用该方法的变量需要是有效的
final
SomeClass::func
,这取决于
func
是静态方法还是实例方法

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

(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);
其中,
\uu somefinaltemporation
在方法引用被评估的点被分配给
示例
,因此如果
示例
稍后更改,仍然使用
示例
的早期值调用该方法


[第四种是
SomeClass::new
,它将参数传递给构造函数。我想就这些了。]

根据Joshua Bloch在他的《有效Java》(第三版)中的说法,有5种类型的用例可供方法参考

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);
    }
}