可选<String> 映射函数returns null

Optional<String> map function returns null

有人可以帮我处理下面的代码吗?我想要一个使用 Optional 函数的等价物。

public String getMyRequiredValue(Optional<String> value) {
    if(value.isPresent()) {
        Optional<String> optionVal = getAnotherValue(value.get());
        if(optionVal.isPresent()) {
            return optionVal.get();
        } else {
            return null;
        }
    } else {
        return "Random";
    }
}

public Optional<String> getAnotherValue(String value) { ... }

请注意,我试过了,但它不起作用

return value.map(lang -> getAnotherValue(lang).orElse(null)).orElse("Random");

不起作用的是 - 当值存在并且 getAnotherValue returns Optional.empty() 我希望原始函数为 return null.现在 returning "Random"

我的假设是因为 map 方法 returns null 它被 "Random" 取代。

注意原来的代码是别人写的。因为它有很多依赖项,所以我无法更改 input/output 参数。 :(

@Andreas在评论中提出的解决方案:

public String getMyRequiredValue(Optional<String> value) {
    return value.isPresent() ? getAnotherValue(value.get()).orElse(null) : "Random";
}

我第一个想到的解决方案。它打破了建议我们总是需要在调用 get() 之前检查 isPresent() 并引入异常处理的规则。所以还是坚持第一个想法比较好。

public String getMyRequiredValue2(Optional<String> value) {
    try {
        return getAnotherValue(value.get()).orElse(null);
    } catch (NoSuchElementException e) {
        return "Random";
    }
}

我看到你试图利用 mapflatMap。如果它们导致 Optional.empty(),则不清楚 null 的来源:它可能是 valuegetAnotherValue(value.get()).

我们可以通过将来自 value.get() 的值保存到 Holder<String>:

来跟踪它
public String getMyRequiredValue3(Optional<String> value) {
    final Holder<String> holder = new Holder<>();
    return value.flatMap(i -> getAnotherValue(holder.value = i))
                .orElse(holder.value == null ? "Random" : null);
}

同样,第一种方法仍然胜过此方法。


编辑:正如@Holder所指出的,我们不需要前面示例中的Holder。相反,我们可以检查 value.isPresent()

public String getMyRequiredValue4(Optional<String> value) {
    return value.flatMap(this::getAnotherValue) 
                .orElse(value.isPresent() ? null : "Random");
}