gpt4 book ai didi

Java 8 java.util.Map#computeIfAbsent 与 java.util.Optional

转载 作者:行者123 更新时间:2023-11-29 08:44:43 25 4
gpt4 key购买 nike

假设我有一个实现为 java.util.Map 的缓存,它存储键的(任意)值。由于值不是强制存在的,缓存返回一个 java.util.Optional 并且能够提供一个 java.util.function.Supplier 来计算值对于给定的不存在的 key 。

我第一个天真的方法是

public class Cache0 {

private final Map<String, String> mapping = new HashMap<>();

public Optional<String> get(String key, Supplier<Optional<String>> supplier) {
final Optional<String> valueOptional;

if (this.mapping.containsKey(key)) {
final String value = this.mapping.get(key);

valueOptional = Optional.of(value);
} else {
valueOptional = supplier.get();

if (valueOptional.isPresent()) {
this.mapping.put(key, valueOptional.get());
}
}

return valueOptional;
}
}

但我发现这非常不雅,当我了解 java.util.Map#computeIfAbsent 时,我将代码更改为以下内容

public class Cache1 {

private final Map<String, String> mapping = new HashMap<>();

public Optional<String> get(String key, Supplier<Optional<String>> supplier) {
final String value = this.mapping.computeIfAbsent(key, absentKey -> this.getValue(supplier));

return Optional.ofNullable(value);
}

private String getValue(Supplier<Optional<String>> supplier) {
return supplier.get()
.orElse(null);
}
}

但现在困扰我的是 java.util.Optional#ofNullablegetValuenull 结果的冗余使用为 java.util.Map#computeIfAbsent 提供不插入 map 的“默认”值所需的方法。

在理想情况下,像下面这样的事情是可能的

public class Cache2 {

private final Map<String, String> mapping = new HashMap<>();

public Optional<String> get(String key, Supplier<Optional<String>> supplier) {
return this.mapping.computeIfAbsent(key, absentKey -> supplier.get());
}
}

如果第二个参数表示一个空的 java.util.Optional 并返回一个 java.util,java.util.Map#computeIfAbsent 将跳过插入.Optional#empty 但不幸的是,使用 java.util.Optional#empty 作为 java.util.Map#computeIfAbsent 的“默认”插入值是不受支持,代码无法编译。

另一种可能性是将 String 的映射存储到 java.util.Optional 但随后 java.util.Map 将将 java.util.Optional#empty 存储为再次与我的用例相矛盾的值,以强制存储无效映射并稍后手动删除/替换它们。

public class Cache3 {

private final Map<String, Optional<String>> mapping = new HashMap<>();

public Optional<String> get(String key, Supplier<Optional<String>> supplier) {
return this.mapping.computeIfAbsent(key, absentKey -> supplier.get());
}
}

有没有人知道处理这种用例的更好方法,或者我是否必须回退到我的 Cache1 实现?

最佳答案

为了做这种事情,我通常在我的 map 中使用一个 Optional - 这种方式 map.get()!=null意味着我已经缓存了访问和 map.get().isPresent()告诉我是否返回了一个合理的值。

在这种情况下,我会使用 Suplier<String>返回 null当值不存在时。然后实现看起来像这样:

public class Cache {
private final Map<String, Optional<String>> mapping = new HashMap<>();

public Optional<String> get(String key, Suplier<String> supplier) {
return mapping.computeIfAbsent(key,
unused -> Optional.ofNullable(supplier.get()) );
}
}

不存在的键确实被插入到 map 中,但被标记为缺失。

关于Java 8 java.util.Map#computeIfAbsent 与 java.util.Optional,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37203591/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com