lambda表达式与实例化方法引用之间的不同行为 [英] Different behavior between lambda expression and method reference by instantiation

查看:85
本文介绍了lambda表达式与实例化方法引用之间的不同行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知,lambda表达式可以被方法引用替换而没有任何问题.我的IDE表示相同,但​​以下示例却相反. 该方法引用显然会返回相同的对象,而lambda表达式每次都会返回新的对象.

As I know lambda expression can be replaced by method reference without any issues. My IDEs say the same, but the following example shows the opposite. The method reference clearly returns the same object, where as lambda expression returns new objects each time.

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Instance {

    int member;

    Instance set(int value){
        this.member = value;
        return this;
    }

    @Override
    public String toString() {
        return member + "";
    }

    public static void main(String[] args) {

        Stream<Integer> stream1 = Stream.of(1, 2, 3, 4);
        Stream<Integer> stream2 = Stream.of(1, 2, 3, 4);

        List<Instance> collect1 = stream1.map(i -> new Instance().set(i)).collect(Collectors.toList());
        List<Instance> collect2 = stream2.map(new Instance()::set).collect(Collectors.toList());

        System.out.println(collect1);
        System.out.println(collect2);
    }
}

这是我的输出:

[1, 2, 3, 4]
[4, 4, 4, 4]

推荐答案

方法引用表达式求值的时间与 哪些lambda表达式.
使用在::之前具有表达式(而不是类型)的方法引用,将立即对子表达式进行求值,然后将求值的结果存储并重新使用.
所以在这里:

The timing of method reference expression evaluation differs from which of lambda expressions.
With a method reference that has an expression (rather than a type) preceding the :: the subexpression is evaluated immediately and the result of evaluation is stored and reused then.
So here :

new Instance()::set

new Instance()进行一次评估.

来自 15.12.4 .方法调用的运行时评估(重点是我的):

方法参考表达式评估的时间更加复杂 比lambda表达式(第15.27.4节)大.方法参考时 expression在:: ::之前有一个表达式(而不是类型) 分隔符,该子表达式将立即求值.的结果 评估将一直存储到相应功能的方法为止 接口类型被调用;此时,结果将用作 调用的目标参考. 这表示表达式 ::分隔符之前的内容仅在程序 遇到方法引用表达式,并且不重新评估 功能接口类型上的后续调用.

The timing of method reference expression evaluation is more complex than that of lambda expressions (§15.27.4). When a method reference expression has an expression (rather than a type) preceding the :: separator, that subexpression is evaluated immediately. The result of evaluation is stored until the method of the corresponding functional interface type is invoked; at that point, the result is used as the target reference for the invocation. This means the expression preceding the :: separator is evaluated only when the program encounters the method reference expression, and is not re-evaluated on subsequent invocations on the functional interface type.

这篇关于lambda表达式与实例化方法引用之间的不同行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆