将Java 8 Optionals与条件AND结合使用

Tar*_*deX 6 java optional logical-operators java-8 java-stream

我的问题是我有两个或更多包含不同类型的Optionals.我想执行一个只有在所有选项都不为空时才能执行的操作.

目前我这样做:

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

    if(userOptional.isPresent() && caseOptional.isPresent()) {
        caseOptional.get().getProcess().setDesigner(userOptional.get());
    }
Run Code Online (Sandbox Code Playgroud)

在我看来,if条件感觉不对.我知道可以使用orElse链接Optionals.但在我的情况下,我不想要一个合乎逻辑的Else.有没有办法创建和AND运算符,以组合两个或更多类似于这个PSEUDO代码的Optionals?

caseOptional.and.userOptional.ifPresent((theCase,user) -> //Perform Stuff);
Run Code Online (Sandbox Code Playgroud)

Hol*_*ger 9

有一个逻辑AND操作,但没有(简单)方法将其转换为双值Optional,换句话说,这(再次)遭受缺少对或元组类型.例如

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

AbstractMap.SimpleEntry用作缺席元组类型的替身.

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

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

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

caseOptional.map(PatientCase::getProcess)
            .ifPresent(p -> userOptional.ifPresent(p::setDesigner));
Run Code Online (Sandbox Code Playgroud)

要么

caseOptional.ifPresent(c -> userOptional.ifPresent(u -> c.getProcess().setDesigner(u)));
Run Code Online (Sandbox Code Playgroud)

代替.


Ser*_*kin 6

没有直接的方法。

STRAM allMatch会像ifPresent许多选配:

Stream.of(optional1, optional2, ...).allMatch(Optional::isPresent)
Run Code Online (Sandbox Code Playgroud)

  • 使用这种技术,我可以验证所有选项都存在。但是不可能链接更多的函数调用。这一步必须再次使用 if 子句控制,稍后我必须解开这些选项。但是当验证两个以上的选项时,编码开销要小一些,所以它的方向是正确的。 (2认同)