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

时间:2016-09-23 08:45:36

标签: java java-8 java-stream optional logical-operators

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

目前我这样做:

    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运算符,以组合两个或更多的Optionals 类似于这个PSEUDO代码?

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

3 个答案:

答案 0 :(得分:7)

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

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)));

代替。

答案 1 :(得分:4)

没有直接的方式。

Stram allMatch将像ifPresent一样用于许多选项:

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

答案 2 :(得分:0)

我知道问题本身已经得到解答,但通常,可选1(称为“ A”)和可选2(称为“ B”)组合的所有状态都可以通过链接map()orElse()或类似的链接获得。这类问题的关键是要记住,Optional.map()内部应用的函数仅适用于“真实”值。

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

因此,map()处理Optional不为空的情况,而orElse()处理Optional为空的情况。