可选的<String> 映射函数返回 null

mes*_*eso 5 java refactoring optional-parameters optional java-8

有人可以帮我处理下面的代码吗?我想要一个等效的使用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) { ... }
Run Code Online (Sandbox Code Playgroud)

只是一个说明我试过这个,但它不起作用

return value.map(lang -> getAnotherValue(lang).orElse(null)).orElse("Random");
Run Code Online (Sandbox Code Playgroud)

不起作用的是 - 当值存在并getAnotherValue返回时,Optional.empty()我希望原始函数返回null。它"Random"现在正在返回。

我的假设是因为该map方法返回null它被替换为"Random".

请注意,原始代码是由其他人编写的。因为它有很多依赖项,所以我无法更改输入/输出参数。:(

And*_*lko 5

@Andreas在评论中最初建议的解决方案:

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

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

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

我已经看到你试图利用mapflatMap。如果结果为Optional.empty(),则不清楚从何null而来:它可能是valuegetAnotherValue(value.get())

我们可以通过将来自的值保存value.get()到 a 中来跟踪它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);
}
Run Code Online (Sandbox Code Playgroud)

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


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

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

  • 对控制流使用异常是一种反模式。我认为您甚至不应该在您的回答中提及该选项,或者至少更清楚地表明这不是一个好主意。 (4认同)