常规实例化和实例化之间的区别,包括方法参考

时间:2020-07-21 07:51:42

标签: java java-8 java-stream method-reference

为什么在第一种情况下SomeClass只实例化一次,而在第二种情况下为什么n次,其中n是流中的元素数?

List<SomeClass> list = stream.map(new SomeClass()::method)
                            .collect(Collectors.toList());

List<SomeClass> list = stream.map(a -> {return new SomeClass().method(a);})
                            .collect(Collectors.toList());

在这种情况下,方法“方法”返回对象本身(=返回此对象)。

因此,在第一种情况下,列表仅包含一个对象,但是包含n次。在第二种情况下,列表包含n个不同的对象。

要重现该问题: 主要:

Arrays.asList(true, false, true, false).stream().map(new SomeClass()::method)
                                                .collect(Collectors.toList());

System.out.println("----------------------");
        
Arrays.asList(true, false, true, false).stream().map(a -> {return new SomeClass().method(a);})
                .collect(Collectors.toList());

和SomeClass.java:

public class SomeClass {
    
    public SomeClass() {
        System.out.println(this);
    }
    
    public SomeClass method(Boolean b) {
        return this;
    }
}

2 个答案:

答案 0 :(得分:7)

方法引用只有四种(请参见this page中的“方法引用的种类”):

  • 对静态方法的引用
  • 对特定对象的实例方法的引用
  • 参考特定类型的任意对象的实例方法
  • 对构造函数的引用

没有什么方法引用可以“每次创建一个新对象”,无论如何。 new SomeClass()::methodName是第二种。它指的是一个特定对象的方法methodName。该对象是新创建的SomeClass对象。调用该方法时,它不会再创建任何SomeClass对象,因为它是对您新创建的特定 {em> someMethod对象的 SomeClass的引用

另一方面,由于SomeClassnew SomeClass()内部,因此每次调用时lambda表达式都会创建一个新的{ ... }

答案 1 :(得分:5)

因为在第一个代码段中您仅调用一次new SomeClass(),因为:

List<SomeClass> list = stream.map(new SomeClass()::method)
                             .collect(Collectors.toList());

实际上等于:

SomeClass s = new SomeClass();
List<SomeClass> list = stream.map(a -> s.method(a))
                             .collect(Collectors.toList());

您在实例method()上调用方法s,在第一个代码片段中,该实例没有保存到变量中,而是直接使用