Lambda 使用新创建的实例理解方法引用

Lambda 使用新创建的实例理解方法引用,lambda,java-8,method-reference,Lambda,Java 8,Method Reference,我完全理解此表格: Set<T> set = new HashSet<>(); list.stream().allMatch(t -> set.add(t)); // And that list.stream().allMatch(set::add); Set Set=newhashset(); list.stream().allMatch(t->set.add(t)); //那 list.stream().allMatch(set::add); 但是这个特别的

我完全理解此表格:

Set<T> set = new HashSet<>();
list.stream().allMatch(t -> set.add(t));
// And that
list.stream().allMatch(set::add);
Set Set=newhashset();
list.stream().allMatch(t->set.add(t));
//那
list.stream().allMatch(set::add);
但是这个特别的例子让我很困惑:

list.stream().allMatch(new HashSet<>()::add);
list.stream().allMatch(新HashSet()::add);
最有趣的是hashset只实例化了一次


创建于

它与第一个表达式相同,只是没有在上下文中保留对新创建集的引用。如果在调用
allMatch
之后不需要集合的值,则它是相同的。它本质上是一个方法引用表达式,具有新创建的
HashSet
实例。虽然乍一看可能会混淆,
HashSet
只创建了一次,然后方法引用绑定到这个新创建的实例,并在计算
allMatch
操作时使用


虽然它可能是一个有效的解决方案,但它可能是危险的,特别是对于非顺序(并行)流管道,因为它违反了API合同中
allMatch
谓词的要求。

它与第一个表达式相同,只是没有在上下文中保留对新创建集的引用。如果在调用
allMatch
之后不需要集合的值,则它是相同的。它本质上是一个方法引用表达式,具有新创建的
HashSet
实例。虽然乍一看可能会混淆,
HashSet
只创建了一次,然后方法引用绑定到这个新创建的实例,并在计算
allMatch
操作时使用


虽然这可能是一个有效的解决方案,但它可能是危险的,特别是对于非顺序(并行)流管道,因为它违反了API合同中的
allMatch
谓词的要求。

顺便说一句,这与执行语句
时将创建多少个数组的问题类似(int i:new int[]{1,2,4,6,9,42}).
谢谢,这正是我想要的。但这是规范中的内容还是当前的impl详细信息?它在中指定。在结尾,有一个明确的摘要:“当方法引用表达式有表达式(而不是类型)时”在::separator之前,将立即计算该子表达式。[…]这意味着只有当程序遇到方法引用表达式时,才会计算::separator之前的表达式,并且在函数接口类型的后续调用中不会重新计算该表达式。”请看,顺便问一下,这与问题类似,在执行(int i:new int[]{1,2,4,6,9,42})语句时将创建多少数组。谢谢,这正是我要寻找的。但这在规范中或只是当前的impl详细信息中?它在中指定。在其结尾,有一个明确的摘要:当方法引用表达式在::分隔符之前有表达式(而不是类型)时,将立即计算该子表达式。[…]这意味着只有当程序遇到方法引用表达式时,才会对::分隔符前面的表达式求值,并且不会在函数接口类型的后续调用中重新求值。”