将 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为空的情况。
我的问题是我有两个或更多包装不同类型的 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为空的情况。