java - 为什么 Map.compute() 采用 BiFunction

标签 java dictionary hashmap java-8

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

<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#compute-K-java.util.function.BiFunction-" rel="noreferrer noopener nofollow"><code>V compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)</code></a> <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#computeIfPresent-K-java.util.function.BiFunction-" rel="noreferrer noopener nofollow"><code>V computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)</code></a> <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#computeIfAbsent-K-java.util.function.Function-" rel="noreferrer noopener nofollow"><code>V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction)</code></a>

我期待一个普通的 Function<? super V, ? extends V> ,分别将旧值映射到新值。一个 Supplier<? extends V> 为新的值(value)。调用者已经拥有 key (第一个参数),因此函数或供应商已经可以使用它。我发现的所有示例都不使用 key 。我想到的原因:

  • key 必须(有效)final -- 易于管理
  • 有一些花哨易用的方法引用

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

最佳答案

您可能会看到 computeIfPresent作为replaceAll的单项挂件而后者需要键作为参数,但很自然地支持相同的函数作为两个操作的输入,并且 API 在这里一致:它总是提供键作为函数的参数。

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

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

关于java - 为什么 Map.compute() 采用 BiFunction,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34183184/

相关文章:

java - 使用 Apache Spark 进行实时分析

json - Python3 将 'CaseInsensitiveDict' 转换为 JSON

java - 寻找一种用Java制作简单数据库或列表的方法(比HashMap更高级,比JDBC更容易)

Java : HashSet vs. 哈希表

java - 选择随机数来显示胜利或失败的导航游戏

java - 什么是NullPointerException,我该如何解决?

python - 在 Python 中高效创建(播种)大型字典

java - 如何从 ArrayList 复制对象并在 HashMap 中按 int 大小对它们进行排序?

java - 如何使用数据库中的数据更新(刷新)JTable

matlab - 在自定义颜色图中显示矩阵中的值 (Matlab)