首先检查两种方法的声明。
1)OrElse:执行逻辑并将结果作为参数传递。
public T orElse(T other) {
return value != null ? value : other;
}
2)OrElseGet:如果可选值内的值为null,则执行逻辑
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
关于上述声明的一些解释:
“ Optional.orElse”的参数总是被执行,而与对象中的可选值无关(空,空或带值)。使用“ Optional.orElse”时,请始终牢记上述几点,否则在以下情况下使用“ Optional.orElse”可能会带来很大的风险。
风险-1)记录问题:如果orElse中的内容包含任何日志语句:在这种情况下,您每次都将对其进行记录。
Optional.of(getModel())
.map(x -> {
//some logic
})
.orElse(getDefaultAndLogError());
getDefaultAndLogError() {
log.error("No Data found, Returning default");
return defaultValue;
}
风险2)性能问题:如果orElse中的内容是时间密集的:时间密集的内容可以是任何I / O操作数据库调用,API调用,文件读取。如果我们将这些内容放在orElse()中,系统将最终执行无用的代码。
Optional.of(getModel())
.map(x -> //some logic)
.orElse(getDefaultFromDb());
getDefaultFromDb() {
return dataBaseServe.getDefaultValue(); //api call, db call.
}
风险3)非法状态或错误问题:如果orElse内部的内容正在改变某些对象状态:我们可能在另一个地方使用同一对象,请在Optional.map函数中说,这会使我们陷入严重的错误中。
List<Model> list = new ArrayList<>();
Optional.of(getModel())
.map(x -> {
})
.orElse(get(list));
get(List < String > list) {
log.error("No Data found, Returning default");
list.add(defaultValue);
return defaultValue;
}
然后,什么时候可以使用orElse()?
当默认值为某些常量对象enum时,最好使用orElse。在上述所有情况下,我们都可以使用Optional.orElseGet()(仅当Optional包含非空值时执行),而不是Optional.orElse()。为什么??在orElse中,我们传递默认结果值,但是在orElseGet中,我们传递Supplier,并且Supplier的方法仅在Optional中的值为null时才执行。
关键要点:
- 如果包含任何日志语句,请不要使用“ Optional.orElse”。
- 如果包含时间密集型逻辑,请不要使用“ Optional.orElse”。
- 如果正在更改某些对象状态,请不要使用“ Optional.orElse”。
- 如果我们必须返回常量枚举,请使用“ Optional.orElse”。
- 在第1,2点和第3点提到的情况下,最好选择“ Optional.orElseGet”。
我已经在我的中等博客的第二点(“ Optional.map/Optional.orElse”!=“if/else”)中对此进行了解释。使用Java8作为程序员而不是程序员
orElseGet
它时,仅当缺少价值时才呼叫供应商。