java - 短路 JavaOptional.flatMap()

标签 java option-type

这是使用 Java 的 Optional.flatMap() 的一个有趣的困境。我有一个封装 CURIE 的类形式为"foo:bar"或者只是 "bar" 。我还有一个用于将前缀注册到命名空间以及跟踪默认命名空间的类。它有一个方法findNamespaceByPrefix()返回 Optional<URI> (因为前缀可能未注册)和方法 getDefaultNamespace() ,还返回 Optional<URI> (因为可能没有默认 namespace )。

鉴于一些 CURIE,我想找到 namespace 。使用这个很诱人:

Optional<URI> namespace = curie.getPrefix()
    .flatMap(this::findNamespaceByPrefix)
    .or(this::getDefaultNamespace);

但这是错误的。问题是它返回默认 namespace ,即使有前缀但没有 namespace 与该前缀关联。如果 CURIE 中根本没有指示任何前缀,我们只想取回默认 namespace (如果有)。

这是一个解决方案:

Optional<String> prefix = curie.getPrefix();
Optional<URI> namespace = prefix.isPresent()
    ? prefix.flatMap(this::findNamespaceByPrefix)
    : getDefaultNamespace();

我对此很满意,但我觉得它使用三元运算符并使用 Optional.isPresent() 有点不起作用。通常表明有更好的方法来做事。

做任何Optional专家们有更好、更实用的解决方案来“短路”平面映射吗? (我有预感,我可以在管道中使用 OptionalOptional:of 进行多层包装和展开 Optional:get ,但有没有更优雅的东西?)

最佳答案

您应该保留第二级可选,而不是“flatMapping”:

Optional<URI> namespace = curie.getPrefix()
    .map(Application::findNamespaceByPrefix)
    .orElseGet(Application::getDefaultNamespace);

map操作将前缀(如果存在)映射到包装的 Optional<Optional<URI>> 中它要么为空(如果前缀不存在),要么包含 Optional<URI>它要么是空的(如果找不到前缀的命名空间),要么包含实际的命名空间。

还有外部orElseGet仅当包装 Optional 时才会被调用为空,因此您的前缀不存在。

关于java - 短路 JavaOptional.flatMap(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58839663/

相关文章:

haskell - 在返回不同类型的函数中对 monad 进行标记

JavaFX 表行更新

java - 如何通过 jline3 在每行前面添加字符串?

Java 的 Random.nextInt() 产生介于什么和什么之间的数字?

haskell - Haskell 中的模糊模式匹配调度

swift - 我可以使用可选链接为可选属性提供默认值吗?

java - 考虑将 JaCoCo 与 Maven 和 Jenkins 一起使用

java - 在 SharedPreferences 上,将变量类型从 Boolean 更改为 Integer

swift - 我可以通过将可选参数用作参数来检查可选参数是否为 nil 吗?

java - Java 8 的 Optional.ifPresent 和 if-not-Present 的功能风格?