如果 nested Optional 为空,return 另一个可选
If nested Optional is empty, return another optional
我的汽车模型看起来如何
class Car {
// some fields here
Optional<Engine> engine;
}
我如何通过几步完成:
public Optional<Engine> checkEngine (Optional<Car> car) {
Optional<Engine> engine = car
.flatMap(Car::getEngine)
if (engine.isPresent()) {
return engine;
}
return Optional.of(new Engine("At the moment car don't have the engine"));
}
我想在 1 个可选表达式中完成:
public Optional<Engine> checkEngine (Optional<Car> car) {
return car
.flatMap(Car::getEngine)
.orElse(Optional.of(new Car("At the moment car don't have the engine")));
}
但它不起作用,intelij idea 说请求的类型是 Engine,但我返回可选的 Engine。但是方法是可选的
错误正确,您传递的类型错误:
public Optional<Engine> checkEngine (Optional<Car> car) {
return car
.flatMap(Car::getEngine)
.orElse(Optional.of(new Car("At the moment car don't have the engine")));
}
car
是 Optional<Car>
- 我想
Car::getEngine
是 Optional<Engine>
flatMap
取一个 Function<? super T, Optional<U>>
,其中 T
是 Optional
的绑定类型,此处:Car
,结果 U:此处 Engine
。它 return 是 Optional<U>
.
orElse(T)
return 一个已经计算出来的结果。由于我们在 flatMap 之后,T
等于 Engine
.
注意: 我链接到 Javadoc of Java 8.
所以 orElse
中的期望值是 Engine
.
你应该在 flatMap
:
之后停止
public Optional<Engine> checkEngine (Optional<Car> car) {
return car.flatMap(Car::getEngine);
}
而且我认为您不应该像您尝试做的那样return“无效”Engine
:您将永远无法区分引擎丢失的情况和引擎丢失的情况它存在的地方。
你应该扔:
public Engine checkEngine (Optional<Car> car) {
return car.flatMap(Car::getEngine)
.orElseThrow(() -> new IllegalStateException("no engine"));
}
请注意,我将结果从 Optional<Engine>
更改为 Engine
。
在 8 (https://cr.openjdk.java.net/~iris/se/16/latestSpec/api/java.base/java/util/Optional.html#or(java.util.function.Supplier)) 之后的 Java 版本中引入了将两个可选结果加入可选结果的可能性。
在 Java 8 中你必须解决这个问题,例如
public Optional<Engine> checkEngine (Optional<Car> car) {
return car
.flatMap(Car::getEngine)
.map(Optional::of)
.orElse(Optional.of(new Engine("At the moment car doesn't have the engine")));
}
使用 Java 9 or()
它看起来像:
public Optional<Engine> checkEngine (Optional<Car> car) {
return car
.flatMap(Car::getEngine)
.or(() -> Optional.of(new Engine("At the moment car don't have the engine")));
}
详细说明为什么使用 or
有意义:
这种技术乍一看似乎非常复杂 - 事实上 - 仅对于此示例,我更喜欢没有 return 可选的解决方案;
然而这种技术一般来说并不是没有意义的,如果我们有一组回退函数,每个 returning 一个可选的,例如
public Optional<Engine> checkEngine (Optional<Car> car) {
return car
.flatMap(Car::getEngine)
.or(this::fallback1) //only call this expensive method as fallback
.or(this::fallback2); //only call this expensive method as fallback
}
public Optional<Engine> fallback1() {
//some code computing a fallback, but can fail and then returns empty
}
public Optional<Engine> fallback2() {
//some code computing a fallback, but can fail and then returns empty
}
使用这种模式的另一个原因是我们不能假设该方法在最终 return 之前没有 return 真正的 Optionals,例如
public Optional<Engine> checkEngine (Optional<Car> car) {
if (isInvalid()) {
return Optional.empty(); // this is a true error
}
// other code
return car
.flatMap(Car::getEngine)
.or(() -> Optional.of(new Engine("At the moment car don't have the engine"))); // it is not an error if car is empty, because there is a valid default
}
我的汽车模型看起来如何
class Car {
// some fields here
Optional<Engine> engine;
}
我如何通过几步完成:
public Optional<Engine> checkEngine (Optional<Car> car) {
Optional<Engine> engine = car
.flatMap(Car::getEngine)
if (engine.isPresent()) {
return engine;
}
return Optional.of(new Engine("At the moment car don't have the engine"));
}
我想在 1 个可选表达式中完成:
public Optional<Engine> checkEngine (Optional<Car> car) {
return car
.flatMap(Car::getEngine)
.orElse(Optional.of(new Car("At the moment car don't have the engine")));
}
但它不起作用,intelij idea 说请求的类型是 Engine,但我返回可选的 Engine。但是方法是可选的
错误正确,您传递的类型错误:
public Optional<Engine> checkEngine (Optional<Car> car) {
return car
.flatMap(Car::getEngine)
.orElse(Optional.of(new Car("At the moment car don't have the engine")));
}
car
是Optional<Car>
- 我想
Car::getEngine
是Optional<Engine>
flatMap
取一个Function<? super T, Optional<U>>
,其中T
是Optional
的绑定类型,此处:Car
,结果 U:此处Engine
。它 return 是Optional<U>
.orElse(T)
return 一个已经计算出来的结果。由于我们在 flatMap 之后,T
等于Engine
.
注意: 我链接到 Javadoc of Java 8.
所以 orElse
中的期望值是 Engine
.
你应该在 flatMap
:
public Optional<Engine> checkEngine (Optional<Car> car) {
return car.flatMap(Car::getEngine);
}
而且我认为您不应该像您尝试做的那样return“无效”Engine
:您将永远无法区分引擎丢失的情况和引擎丢失的情况它存在的地方。
你应该扔:
public Engine checkEngine (Optional<Car> car) {
return car.flatMap(Car::getEngine)
.orElseThrow(() -> new IllegalStateException("no engine"));
}
请注意,我将结果从 Optional<Engine>
更改为 Engine
。
在 8 (https://cr.openjdk.java.net/~iris/se/16/latestSpec/api/java.base/java/util/Optional.html#or(java.util.function.Supplier)) 之后的 Java 版本中引入了将两个可选结果加入可选结果的可能性。
在 Java 8 中你必须解决这个问题,例如
public Optional<Engine> checkEngine (Optional<Car> car) {
return car
.flatMap(Car::getEngine)
.map(Optional::of)
.orElse(Optional.of(new Engine("At the moment car doesn't have the engine")));
}
使用 Java 9 or()
它看起来像:
public Optional<Engine> checkEngine (Optional<Car> car) {
return car
.flatMap(Car::getEngine)
.or(() -> Optional.of(new Engine("At the moment car don't have the engine")));
}
详细说明为什么使用 or
有意义:
这种技术乍一看似乎非常复杂 - 事实上 - 仅对于此示例,我更喜欢没有 return 可选的解决方案;
然而这种技术一般来说并不是没有意义的,如果我们有一组回退函数,每个 returning 一个可选的,例如
public Optional<Engine> checkEngine (Optional<Car> car) {
return car
.flatMap(Car::getEngine)
.or(this::fallback1) //only call this expensive method as fallback
.or(this::fallback2); //only call this expensive method as fallback
}
public Optional<Engine> fallback1() {
//some code computing a fallback, but can fail and then returns empty
}
public Optional<Engine> fallback2() {
//some code computing a fallback, but can fail and then returns empty
}
使用这种模式的另一个原因是我们不能假设该方法在最终 return 之前没有 return 真正的 Optionals,例如
public Optional<Engine> checkEngine (Optional<Car> car) {
if (isInvalid()) {
return Optional.empty(); // this is a true error
}
// other code
return car
.flatMap(Car::getEngine)
.or(() -> Optional.of(new Engine("At the moment car don't have the engine"))); // it is not an error if car is empty, because there is a valid default
}