【问题标题】:Why doesn't Java have a putIfAbsent(key, supplier) method in Map?为什么 Java 在 Map 中没有 putIfAbsent(key, supplier) 方法?
【发布时间】:2015-01-23 11:55:07
【问题描述】:

我最近发现自己想要一个 java.util.Map 中的 putIfAbsent(...) 版本,您可以提供某种工厂方法来实例化一个对象(如果它不存在)。这将简化很多代码。

这是我修改后的界面:

import java.util.Map;
import java.util.function.Supplier;

/**
 * Extension of the Map Interface for a different approach on having putIfAbsent
 * 
 * @author Martin Braun
 */
public interface SupplierMap<K, V> extends Map<K, V> {

    public default V putIfAbsent(K key, Supplier<V> supplier) {
        V value = this.get(key);
        if(value == null) {
            this.put(key, value = supplier.get());
        }
        return value;
    }

}

现在我的问题是: 是否有另一种(更简单的)方法可以做到这一点,或者我只是忽略了 Java API 中的某些内容?

【问题讨论】:

  • FWIW, Map#putIfAbsent 是用 Java8 添加的。
  • 在 Java 1.8 中有 V putIfAbsent(K key, V value)
  • 我知道,但它只允许提供 Object 而不是 Supplier 方法。
  • 上面的代码有什么问题。我认为它应该有效。

标签: java collections map


【解决方案1】:

computeIfAbsent 不是 putIfAbsent 的 1:1 替代品,因为返回值的约束不匹配。虽然 putIfAbsent 在创建新条目时返回 null,但 computeIfAbsent 始终返回分配的值。

上面建议的默认实现,调用 get 然后 put 可以工作,但它需要在映射中进行两次查找,这破坏了在- 原位替换。

【讨论】:

    【解决方案2】:

    computeIfAbsent不是你想要的吗?

    如果指定的键尚未与值关联(或 映射到 null),尝试使用给定的映射计算其值 函数并将其输入到此映射中,除非为 null。

    实现类似于:

    if (map.get(key) == null) {
        V newValue = mappingFunction.apply(key);
        if (newValue != null) {
             map.put(key, newValue);
        }
    }
    

    所以它不完全是您发布的Supplier&lt;V&gt; 签名,但接近。在映射函数中使用键作为参数绝对是有意义的。

    【讨论】:

    • 啊。我忽略了那个。谢谢:)
    • 是的。作为论点的关键更有意义,这是正确的。我会尽快接受这个答案。
    • Java 7 用户有什么解决方案吗?
    • @shlatchz 不使用标准地图。
    • @lexicore,所以安卓程序员没有其他办法了吗?
    猜你喜欢
    • 2015-11-26
    • 2018-06-19
    • 2021-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-20
    • 2023-01-21
    相关资源
    最近更新 更多