在 Java 8 中展开多个可选变量

2022-09-02 10:27:51

我有以下问题。假设您有 2 个变量Optional

Optional<Contact> c1 = ...
Optional<Contact> c2 = ...

和一个需要 2 个联系人类型的变量的方法

void match(Contact c1, Contact c2) {...}

你需要解开c1和c2 vars的包装,并将它们传递到方法中。Optionalmatch()

我的问题是“在Java 8中,哪种方式最优雅?

到目前为止,我已经找到了2种方法:

  1. 通过使用 isPresent

    if (c1.isPresent() && c2.isPresent()) {
        match(c1.get(), c2.get());
    }
    
  2. 通过使用嵌套 ifPresent

    c1.ifPresent((Contact _c1) -> {
        c2.ifPresent((Contact _c2) -> {
            match(_c1, _c2);
        });
    });
    

在我看来,这两种方式都很糟糕。在Scala中,我可以这样做:

for {
    contact1 <- c1
    contact2 <- c2
} yield {
    match(contact1, contact2);
}

在Java 8中,有没有办法比我上面概述的更整洁?


答案 1

您在scala中提供的解决方案只是用于在内部使用flatMaps的语法糖。您也可以在Java 8中使用平面图(但是它没有语法糖)。

c1.flatMap(contact1 -> c2.flatMap(contact2 -> match(contact1, contact2)));

它与您提供的解决方案2几乎相同。你也可以使用来自 https://github.com/aol/cyclops-react(我是贡献者之一)或任何其他函数式java 8库的适用函子。

应用函子

Optional<String> o3 = Maybe.fromOptional(o1).ap2(String::concat).ap(o2).toOptional();

用于理解

Do.add(o1)
    .add(o2)
    .yield(a->b->a.concat(b));

答案 2

你可以在Java 8中将Scala解理解为map/flatMap,使用如下函数:

public static <T,K,V> Optional<V> map2(Optional<T> opt1, Optional<K> opt2, BiFunction<T, K, V> f) {
    Optional<V> result = opt1.flatMap(t1 -> opt2.map(t2 -> f.apply(t1, t2)));
    return result;
}

然后传递函数匹配


推荐