我正在尝试做这样的事情:
private String getStringIfObjectIsPresent(Optional<Object> object){
object.ifPresent(() ->{
String result = "result";
//some logic with result and return it
return result;
}).orElseThrow(MyCustomException::new);
}
这是行不通的,因为 ifPresent 将 Consumer 函数接口作为参数,其中有 void accept(T t)。它不能返回任何值。还有其他办法吗?
实际上您正在搜索的是:Optional.map。您的代码将如下所示:
object.map(o -> "result" /* or your function */)
.orElseThrow(MyCustomException::new);
如果可以的话,我宁愿省略通过
Optional
。最后,在这里使用 Optional
你什么也得不到。另一种稍微不同的变体:
public String getString(Object yourObject) {
if (Objects.isNull(yourObject)) { // or use requireNonNull instead if NullPointerException suffices
throw new MyCustomException();
}
String result = ...
// your string mapping function
return result;
}
如果您由于另一次调用而已经拥有
Optional
-对象,我仍然建议您使用 map
-方法,而不是 isPresent
等,原因只有一个,我发现它更具可读性(显然是一个主观决定;-))。
这里有两个选项:
将
ifPresent
替换为 map
并使用 Function
代替 Consumer
private String getStringIfObjectIsPresent(Optional<Object> object) {
return object
.map(obj -> {
String result = "result";
//some logic with result and return it
return result;
})
.orElseThrow(MyCustomException::new);
}
使用
isPresent
:
private String getStringIfObjectIsPresent(Optional<Object> object) {
if (object.isPresent()) {
String result = "result";
//some logic with result and return it
return result;
} else {
throw new MyCustomException();
}
}
请改用
map
功能。它转换可选值内的值。
像这样:
private String getStringIfObjectIsPresent(Optional<Object> object) {
return object.map(() -> {
String result = "result";
//some logic with result and return it
return result;
}).orElseThrow(MyCustomException::new);
}
我更喜欢在确保值可用后进行映射
private String getStringIfObjectIsPresent(Optional<Object> object) {
Object ob = object.orElseThrow(MyCustomException::new);
// do your mapping with ob
String result = your-map-function(ob);
return result;
}
或一个衬垫
private String getStringIfObjectIsPresent(Optional<Object> object) {
return your-map-function(object.orElseThrow(MyCustomException::new));
}
你举的例子不是一个好例子。可选值不应作为参数发送到另一个函数中。好的做法是始终将非空参数发送到函数中。这样我们就始终知道输入不会为空。这可以减少我们的代码不确定性。
从 Java 9 开始,我们有了
ifPresentOrElse()
。不幸的是,第二个参数是 Runnable
而不是 exceptionSupplier。
我们可以添加一个辅助方法来让它变得漂亮。
public <X extends Throwable> Runnable toThrow(Supplier<X> exceptionSupplier) throws X {
throw exceptionSupplier.get();
}
// Pretty now
opt.ifPresentOrElse(obj::setter, toThrow(IllegalStateException::new));