普通实例化和包含方法引用的实例化的区别
Difference between normal instantiation and instantiation including 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());
本例中的方法“method”return对象本身(=returnthis)。
所以在第一种情况下,列表只包含一个对象,但是有 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;
}
}
因为在第一个片段中您只调用了一次 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());
您在实例 s
上调用方法 method()
,在第一个代码片段中,该实例并未保存到变量中,而是直接使用
方法引用只有四种(参见this page中的“方法引用的种类”):
- 引用静态方法
- 引用特定对象的实例方法
- 引用特定类型的任意对象的实例方法
- 对构造函数的引用
不存在一种“每次都创建一个新对象”的方法引用,不管那是什么意思。 new SomeClass()::methodName
属于第二种。它指的是一个特定对象的方法methodName
。该对象是新创建的 SomeClass
对象。当调用该方法时,它不再创建任何 SomeClass
对象,因为它是对 那个特定 SomeClass
对象的 someMethod
的引用你是新创建的。
另一方面,lambda 表达式在每次调用时都会创建一个新的 SomeClass
,因为 new SomeClass()
在 { ... }
.
中
为什么第一种情况下 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());
本例中的方法“method”return对象本身(=returnthis)。
所以在第一种情况下,列表只包含一个对象,但是有 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;
}
}
因为在第一个片段中您只调用了一次 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());
您在实例 s
上调用方法 method()
,在第一个代码片段中,该实例并未保存到变量中,而是直接使用
方法引用只有四种(参见this page中的“方法引用的种类”):
- 引用静态方法
- 引用特定对象的实例方法
- 引用特定类型的任意对象的实例方法
- 对构造函数的引用
不存在一种“每次都创建一个新对象”的方法引用,不管那是什么意思。 new SomeClass()::methodName
属于第二种。它指的是一个特定对象的方法methodName
。该对象是新创建的 SomeClass
对象。当调用该方法时,它不再创建任何 SomeClass
对象,因为它是对 那个特定 SomeClass
对象的 someMethod
的引用你是新创建的。
另一方面,lambda 表达式在每次调用时都会创建一个新的 SomeClass
,因为 new SomeClass()
在 { ... }
.