[英]Short-circuiting Java Optional.flatMap()
這是使用 Java 的Optional.flatMap()
的一個有趣的難題。 我有一個 class 以"foo:bar"
或只是"bar"
的形式封裝CURIE 。 我還有一個 class 用於注冊命名空間的前綴,以及跟蹤默認命名空間。 它有一個方法findNamespaceByPrefix()
返回一個Optional<URI>
(因為前綴可能未注冊)和一個方法getDefaultNamespace()
,也返回一個Optional<URI>
(因為可能沒有默認命名空間)。
給定一些 CURIE,我想找到命名空間。 使用這個很誘人:
Optional<URI> namespace = curie.getPrefix()
.flatMap(this::findNamespaceByPrefix)
.or(this::getDefaultNamespace);
但這是錯誤的。 問題是它返回默認命名空間,即使有前綴但沒有命名空間與該前綴相關聯。 如果 CURIE 中根本沒有指示前綴,我們只想取回默認命名空間(如果有)。
這是一個解決方案:
Optional<String> prefix = curie.getPrefix();
Optional<URI> namespace = prefix.isPresent()
? prefix.flatMap(this::findNamespaceByPrefix)
: getDefaultNamespace();
我對此很好,但它讓我覺得它使用三元運算符有點不起作用,並且使用Optional.isPresent()
通常表明有更好的方法來做事。
是否有任何Optional
專家有更好、更實用的解決方案來“短路”平面映射? (我有一種預感,我可以在管道中使用Optional:of
和Optional:get
對Optional
進行多層包裝和展開,但有沒有更優雅的東西?)
而不是“flatMapping”,你應該保持你的第二級可選:
Optional<URI> namespace = curie.getPrefix()
.map(Application::findNamespaceByPrefix)
.orElseGet(Application::getDefaultNamespace);
map
操作將一個前綴(如果存在)映射到一個包裝的Optional<Optional<URI>>
中,該前綴要么為空(如果前綴不存在),要么包含一個空的Optional<URI>
(如果找不到前綴)或包含實際的命名空間。
並且外部orElseGet
僅在包裝Optional
為空並且因此不存在您的前綴時才被調用。
您檢查 null 前綴
Optional<URI> namespace = prefix
.filter(Objects::nonNull)
.flatMap(this::findNamespaceByPrefix)
.or(this::getDefaultNamespace);
您可以按如下方式對其進行測試:
public static void main(String[] args) {
test(Optional.ofNullable(null));
test(Optional.ofNullable("yourprefix"));
}
private static void test(Optional<String> prefix) {
Optional<URI> namespace2 = prefix
.filter(Objects::nonNull)
.flatMap(p -> Optional.of(URI.create(p)))
.or(() -> Optional.of(URI.create("default")));
System.out.println(namespace2);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.