簡體   English   中英

短路 Java Optional.flatMap()

[英]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:ofOptional:getOptional進行多層包裝和展開,但有沒有更優雅的東西?)

而不是“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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM