将 Java 8 个可选项与条件 AND 组合

Combine Java 8 Optionals with conditional AND

我的问题是我有两个或更多包装不同类型的 Optional。 我想执行一个只有在所有可选值都不为空的情况下才能执行的操作。

目前我是这样做的:

    Optional<PatientCase> caseOptional = patientCaseRepository.findOneById(caseId);
    Optional<User> userOptional = userRepository.findOneById(caseId);

    if(userOptional.isPresent() && caseOptional.isPresent()) {
        caseOptional.get().getProcess().setDesigner(userOptional.get());
    }

在我看来,if 条件感觉不对。 我知道可以使用 orElse 链接 Optionals。 但就我而言,我不想要一个合乎逻辑的 Else。 有没有一种方法可以创建 and AND 运算符以组合两个或多个 Optionals 类似于此伪代码 ?

caseOptional.and.userOptional.ifPresent((theCase,user) -> //Perform Stuff);

有一个逻辑与操作,但是没有(简单的)方法可以将它变成一个双值Optional,换句话说,这(再次)遭受了对或元组的缺失类型。例如

caseOptional.flatMap(theCase -> userOptional
        .map(user -> new AbstractMap.SimpleEntry<>(theCase, user)))
    .ifPresent(e -> e.getKey().getProcess().setDesigner(e.getValue()));

它使用 AbstractMap.SimpleEntry 作为不存在的元组类型的替代。

另一种方法是使用单例映射作为对:

caseOptional.flatMap(theCase -> userOptional
        .map(user -> Collections.singletonMap(theCase, user)))
    .ifPresent(m -> m.forEach((c, u) -> c.getProcess().setDesigner(u)));

但在这种特定情况下,您可以使用更简单的方法

caseOptional.map(PatientCase::getProcess)
            .ifPresent(p -> userOptional.ifPresent(p::setDesigner));

caseOptional.ifPresent(c -> userOptional.ifPresent(u -> c.getProcess().setDesigner(u)));

相反。

没有直接的方法。

Stram allMatch 将像 ifPresent 一样对许多选项起作用:

Stream.of(optional1, optional2, ...).allMatch(Optional::isPresent)

我知道问题本身已经得到解答,但总的来说,optional1(称为“A”)和 optional2(称为“B”)组合的所有状态可以通过链接 map()orElse() 或类似方式获得。这类问题的关键是要记住 Optional.map() 中应用的函数仅应用于 'real' 值。

A.map(a->B.map(b->"A&&B").
           orElse("A&&!B")).
  orElse(B.map(b->"!A&&B").
           orElse("!A&&!B"));

所以map()处理Optional不为空的情况,orElse()处理Optional为空的情况。