【问题标题】:Understanding method reference with newly created instance使用新创建的实例了解方法引用
【发布时间】:2016-11-03 14:07:10
【问题描述】:

我完全理解这个表格:

Set<T> set = new HashSet<>();
list.stream().allMatch(t -> set.add(t));
// And that
list.stream().allMatch(set::add);

但是这个临时实例真的让我很困惑:

list.stream().allMatch(new HashSet<>()::add);

最有趣的是hashset只实例化了一次。

创立于this topic

【问题讨论】:

  • 这个顺便提一下,和问题类似,执行for(int i: new int[] { 1, 2, 4, 6, 9, 42 }) …语句时会创建多少个数组
  • 谢谢,这正是我想要的。但这在规范中还是只是当前的实现细节?
  • JLS§15.13.3. Run-Time Evaluation of Method References中指定。最后,有一个清晰的摘要:“当方法引用表达式在 :: 分隔符之前有一个表达式(而不是类型)时,会立即计算该子表达式。 [...] 这意味着 :: 分隔符之前的表达式仅在程序遇到方法引用表达式时才被评估,并且不会在功能接口类型的后续调用中重新评估。

标签: lambda java-8 method-reference


【解决方案1】:

它与第一个表达式相同,只是您不在上下文中保留对新创建集合的引用。如果您在allMatch 调用之后不需要该集合的值,则相同。它本质上是一个方法引用表达式,带有新创建的HashSet 实例。虽然乍一看可能会让人感到困惑,但 HashSet 只创建一次,然后方法引用绑定到这个新创建的实例并用于评估 allMatch 操作。

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

【讨论】:

    猜你喜欢
    • 2011-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-24
    • 2011-08-03
    相关资源
    最近更新 更多