如何减少不同类型的 Optionals?

How to reduce Optionals of different types?

我知道可以合并相同类型的选项。

public static void main(String[] args) {
    var foo = Stream.of(Optional.of("a"), Optional.of("b"))
        .flatMap(Optional::stream)
        .reduce((a, b) -> a + "-" + b)
        .orElse(null);
    System.out.println(foo); // prints "a-b"
}

但是,我正在努力合并 不同 类型的选项。

public class Example {

    record A(){}

    record B(){}

    record C(A a, B b){}

    public static void main(String[] args) {
        var foo = Stream.of(Optional.of(new A()), Optional.of(new B()))
            .flatMap(Optional::stream)
            .reduce((a, b) -> new C(a, b))
            .orElse(null);
        System.out.println(foo);
    }
    
}

这不起作用,我遇到了错误。

Type mismatch: cannot convert from Example.C to capture#1-of ? extends Record

我尝试了不同的类型转换版本,但到目前为止没有成功。 有什么想法吗?

这显然是一个微不足道且非常简单的示例。现实生活中我有两种方法

  1. 第一个 returns 类型为 User
  2. 的可选
  3. 第二个 returns 类型 Animal
  4. 的可选

当两者都成功/不为空时,我想调用一个方法myMethod(User user, Animal animal)。所以,问题基本上是关于加入/合并两个可选值,然后处理包含的值。

如果您有固定数量的可选值,请使用 flatMap 链,以另一个 flatMapmap 结尾,以便将它们全部映射到 Optional<AnotherType>.

在两个可选的情况下,这看起来像:

Optional<A> aOpt = Optional.of(new A());
Optional<B> bOpt = Optional.of(new B());
Optional<C> c = aOpt.flatMap(a ->
                bOpt.map(b ->
                    new C(a, b)));

您可以将其概括为 n 个可选值:

// opt1 to opt5 can all be different types of optionals
opt1.flatMap(a ->
opt2.flatMap(b ->
opt3.flatMap(c ->
opt4.flatMap(d ->
opt5.map(e -> // if f returns another optional, you'd use flatMap here too
    f(a, b, c, d, e))))));