【问题标题】:Why does Map.compute() take a BiFunction为什么 Map.compute() 采用 BiFunction
【发布时间】:2015-12-09 15:52:55
【问题描述】:

我不明白为什么Map.compute()Map.computeIfPresent()BiFunction 参数以及Map.computeIfAbsent()Function

@987654321@ @987654322@ @987654323@

我希望有一个普通的Function<? super V, ? extends V>,将旧值映射到新值。 Supplier<? extends V> 表示新值。调用者已经拥有密钥(第一个参数),因此函数或供应商已经可以使用它。我发现的所有示例都没有使用密钥。我想到的原因:

  • 密钥必须(有效地)final -- 这很容易管理
  • 有一些精美易用的方法参考

但我不认为这些是这种设计的可行理由。你有什么想法吗?

【问题讨论】:

  • 在 lambda 中要捕获的变量少了一个。
  • “调用者已经拥有密钥”……除非 BiFunction 是一个方法引用,在这种情况下,该方法将不知道密钥的值,除非该密钥作为参数传入。跨度>
  • @steffen:它可以区分捕获和非捕获,请参阅stackoverflow.com/a/27524543/2711488
  • @VGR,有时拥有关键参数只是不必要的负担。没有它我们可以写map.computeIfAbsent(key, ArrayList::new).add(value),现在我们需要写map.computeIfAbsent(key, k -> new ArrayList<>()).add(value)引入无用的k
  • @Tagir Valeev:确实,我不需要钥匙的情况比我需要钥匙的情况更多。但是,在我的项目中,某些函数转换实用程序方法是标准工具集的一部分,因为它们在各个地方都派上用场,即我可以使用 map.computeIfAbsent(key, dropArg(ArrayList::new)). …

标签: java dictionary hashmap java-8


【解决方案1】:

您可能会看到computeIfPresentreplaceAll 的单入口挂件,而后者需要将键作为参数,但很自然地支持相同的功能作为两个操作的输入和API 在这里一致:它始终将密钥作为参数提供给函数。

通常,提供密钥会提高现有函数的可重用性,无论是方法引用还是BiFunction 接口的普通class 实现(即非lambda)。但是考虑到现有的 JRE 实现,这种可重用性也可能会影响 lambda 表达式的性能:

As described here,从周围上下文中捕获值的 lambda 表达式可能会在每个捕获进程的单独实例中结束,而仅使用其参数的 lambda 表达式(非捕获 lambda)最终将作为单例实例。相反,具有其他未使用的参数对性能没有影响。因此,出于这个原因,最好将密钥作为参数接收。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 2014-01-05
    • 2011-11-25
    • 2012-04-10
    • 1970-01-01
    • 2020-07-18
    相关资源
    最近更新 更多