`Optional.orElse()` 和 `Optional.orElseGet()` 之间的区别
Difference between `Optional.orElse()` and `Optional.orElseGet()`
我想了解 Optional<T>.orElse()
and Optional<T>.orElseGet()
方法之间的区别。
orElse()
方法的描述是 "Return the value if present, otherwise return other."
而 orElseGet()
方法的描述是 "Return the value if present, otherwise invoke other and return the result of that invocation."
orElseGet()
方法采用 Supplier 功能接口,该接口基本上不采用任何参数和 returns T
。
在什么情况下需要使用orElseGet()
?如果你有一个方法 T myDefault()
你为什么不直接做 optional.orElse(myDefault())
而不是 optional.orElseGet(() -> myDefault())
呢?
orElseGet()
似乎没有将 lambda 表达式的执行推迟到稍后的某个时间或其他什么时间,那么它有什么意义呢? (我原以为如果它返回一个更安全的 Optional<T>
会更有用,它的 get()
永远不会抛出 NoSuchElementException
并且 isPresent()
总是 returns true.. .但显然不是,它只是 returns T
就像 orElse()
).
我还缺少其他一些区别吗?
以这两种情况为例:
Optional<Foo> opt = ...
Foo x = opt.orElse( new Foo() );
Foo y = opt.orElseGet( Foo::new );
如果opt
不包含值,两者确实是等价的。但是如果 opt
包含一个值,将创建多少 Foo
个对象?
P.s.: 当然,在这个例子中,差异可能无法衡量,但是如果您必须从远程 Web 服务获取默认值,或者从一个数据库,一下子就变得很重要了。
我来到这里是为了解决 Kudo 提到的问题。
我正在为其他人分享我的经验。
orElse
,或者orElseGet
,就是这个问题:
static String B() {
System.out.println("B()...");
return "B";
}
public static void main(final String... args) {
System.out.println(Optional.of("A").orElse(B()));
System.out.println(Optional.of("A").orElseGet(() -> B()));
}
打印
B()...
A
A
orElse
计算 B() 的值与可选值相互依赖。因此,orElseGet
是懒惰的。
我想说 orElse
和 orElseGet
之间的最大区别在于我们想要评估某些东西以获得 else
条件下的新值。
考虑这个简单的例子 -
// oldValue is String type field that can be NULL
String value;
if (oldValue != null) {
value = oldValue;
} else {
value = apicall().value;
}
现在让我们将上面的示例转换为使用 Optional
以及 orElse
、
// oldValue is Optional type field
String value = oldValue.orElse(apicall().value);
现在让我们将上面的示例转换为使用 Optional
以及 orElseGet
、
// oldValue is Optional type field
String value = oldValue.orElseGet(() -> apicall().value);
当调用 orElse
时,apicall().value
被评估并传递给方法。而在 orElseGet
的情况下,仅当 oldValue
为空时才会进行评估。 orElseGet
允许延迟计算。
简答:
- orElse() 将始终调用给定函数,无论您是否需要,无论
Optional.isPresent()
值如何
- orElseGet() 只会在
Optional.isPresent() == false
时调用给定的函数
在实际代码中,当所需资源获取的成本很高时,您可能需要考虑第二种方法。
// Always get heavy resource
getResource(resourceId).orElse(getHeavyResource());
// Get heavy resource when required.
getResource(resourceId).orElseGet(() -> getHeavyResource())
有关更多详细信息,请考虑以下使用此函数的示例:
public Optional<String> findMyPhone(int phoneId)
区别如下:
X : buyNewExpensivePhone() called
+——————————————————————————————————————————————————————————————————+——————————————+
| Optional.isPresent() | true | false |
+——————————————————————————————————————————————————————————————————+——————————————+
| findMyPhone(int phoneId).orElse(buyNewExpensivePhone()) | X | X |
+——————————————————————————————————————————————————————————————————+——————————————+
| findMyPhone(int phoneId).orElseGet(() -> buyNewExpensivePhone()) | | X |
+——————————————————————————————————————————————————————————————————+——————————————+
当optional.isPresent() == false
时,两种方式没有区别。但是,当optional.isPresent() == true
时,orElse()
不管你想不想,总是调用后面的函数。
最后使用的测试用例如下:
结果:
------------- Scenario 1 - orElse() --------------------
1.1. Optional.isPresent() == true (Redundant call)
Going to a very far store to buy a new expensive phone
Used phone: MyCheapPhone
1.2. Optional.isPresent() == false
Going to a very far store to buy a new expensive phone
Used phone: NewExpensivePhone
------------- Scenario 2 - orElseGet() --------------------
2.1. Optional.isPresent() == true
Used phone: MyCheapPhone
2.2. Optional.isPresent() == false
Going to a very far store to buy a new expensive phone
Used phone: NewExpensivePhone
代码:
public class TestOptional {
public Optional<String> findMyPhone(int phoneId) {
return phoneId == 10
? Optional.of("MyCheapPhone")
: Optional.empty();
}
public String buyNewExpensivePhone() {
System.out.println("\tGoing to a very far store to buy a new expensive phone");
return "NewExpensivePhone";
}
public static void main(String[] args) {
TestOptional test = new TestOptional();
String phone;
System.out.println("------------- Scenario 1 - orElse() --------------------");
System.out.println(" 1.1. Optional.isPresent() == true (Redundant call)");
phone = test.findMyPhone(10).orElse(test.buyNewExpensivePhone());
System.out.println("\tUsed phone: " + phone + "\n");
System.out.println(" 1.2. Optional.isPresent() == false");
phone = test.findMyPhone(-1).orElse(test.buyNewExpensivePhone());
System.out.println("\tUsed phone: " + phone + "\n");
System.out.println("------------- Scenario 2 - orElseGet() --------------------");
System.out.println(" 2.1. Optional.isPresent() == true");
// Can be written as test::buyNewExpensivePhone
phone = test.findMyPhone(10).orElseGet(() -> test.buyNewExpensivePhone());
System.out.println("\tUsed phone: " + phone + "\n");
System.out.println(" 2.2. Optional.isPresent() == false");
phone = test.findMyPhone(-1).orElseGet(() -> test.buyNewExpensivePhone());
System.out.println("\tUsed phone: " + phone + "\n");
}
}
考虑以下代码:
import java.util.Optional;
// one class needs to have a main() method
public class Test
{
public String orelesMethod() {
System.out.println("in the Method");
return "hello";
}
public void test() {
String value;
value = Optional.<String>ofNullable("test").orElseGet(this::orelesMethod);
System.out.println(value);
value = Optional.<String>ofNullable("test").orElse(orelesMethod());
System.out.println(value);
}
// arguments are passed using the text field below this editor
public static void main(String[] args)
{
Test test = new Test();
test.test();
}
}
如果我们这样得到value
:Optional.<String>ofNullable(null)
,orElseGet()和orElse()没有区别,但是如果我们这样得到value
:Optional.<String>ofNullable("test")
、orelesMethod()
在 orElseGet()
中不会被调用,但在 orElse()
中会被调用
下面的例子可以证明两者的区别:
String destroyTheWorld() {
// destroy the world logic
return "successfully destroyed the world";
}
Optional<String> opt = Optional.of("Save the world");
// we're dead
opt.orElse(destroyTheWorld());
// we're safe
opt.orElseGet(() -> destroyTheWorld());
答案也出现在文档中。
public T orElseGet(Supplier<? extends T> other)
:
Return the value if present, otherwise invoke other and return the
result of that invocation.
如果 Optional
存在,Supplier
将不会被调用 。然而,
Return the value if present, otherwise return other.
如果 other
是 returns 字符串的方法,它将被调用,但如果 Optional
存在,则不会返回它的值。
差异非常细微,如果您不注意,就会以错误的方式使用它。
了解 orElse()
和 orElseGet()
之间区别的最佳方法是,如果 Optional<T>
为 null[=,则 orElse()
将始终执行44=]或者不是,但是orElseGet()
只会在Optional<T>
为null时执行。
字典中orElse的意思是:-当某物不存在时执行该部分,但这里矛盾,见下文示例:
Optional<String> nonEmptyOptional = Optional.of("Vishwa Ratna");
String value = nonEmptyOptional.orElse(iAmStillExecuted());
public static String iAmStillExecuted(){
System.out.println("nonEmptyOptional is not NULL,still I am being executed");
return "I got executed";
}
Output: nonEmptyOptional is not NULL,still I am being executed
Optional<String> emptyOptional = Optional.ofNullable(null);
String value = emptyOptional.orElse(iAmStillExecuted());
public static String iAmStillExecuted(){
System.out.println("emptyOptional is NULL, I am being executed, it is normal as
per dictionary");
return "I got executed";
}
Output: emptyOptional is NULL, I am being executed, it is normal as per
dictionary
For orElseGet()
, The method goes as per dictionary meaning, The
orElseGet()
part will be executed only when the Optional is
null.
基准:
+--------------------+------+-----+------------+-------------+-------+
| Benchmark | Mode | Cnt | Score | Error | Units |
+--------------------+------+-----+------------+-------------+-------+
| orElseBenchmark | avgt | 20 | 60934.425 | ± 15115.599 | ns/op |
+--------------------+------+-----+------------+-------------+-------+
| orElseGetBenchmark | avgt | 20 | 3.798 | ± 0.030 | ns/op |
+--------------------+------+-----+------------+-------------+-------+
Remarks: orElseGet()
has clearly outperformed orElse()
for our particular example.
希望它消除了像我这样想要非常基本的地面示例的人的疑虑:)
首先检查两个方法的声明。
1) OrElse: 执行逻辑并将结果作为参数传递。
public T orElse(T other) {
return value != null ? value : other;
}
2) OrElseGet: 如果可选中的值为空则执行逻辑
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操作DB调用,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()?
当默认值是某个常量对象枚举时,更喜欢使用 orElse。在上述所有情况下,我们可以使用 Optional.orElseGet()(仅当 Optional 包含空值时才执行)而不是 Optional.orElse()。为什么??在 orElse 中,我们传递默认结果值,但在 orElseGet 中,我们传递 Supplier 并且 Supplier 的方法仅在 Optional 中的值为 null 时执行。
要点:
- 如果包含任何日志语句,请不要使用“Optional.orElse”。
- 如果包含时间密集型逻辑,请不要使用“Optional.orElse”。
- 如果它正在改变某些对象状态,请不要使用“Optional.orElse”。
- 如果我们必须 return 一个常数,枚举,请使用“Optional.orElse”。
- 第1,2点和第3点提到的情况更喜欢“Optional.orElseGet”
我在第 2 点(“可选。map/Optional.orElse”!=“if/else”)我的中型博客中对此进行了解释。 Use Java8 as a programmer not as a coder
它们都习惯于return一个Optional的默认值,但是如果使用一个方法来产生默认值:
- orElse:总是执行该方法,如果 Optional 不为空
- orElseGet:仅当 Optional 为空时执行它 (+ Performance!)
查看此示例(class 可选示例):
public static void main(String[] args) {
Optional<String> optionalNotEmpty = Optional.of("StringVal");
// orElse: getDefaultValue called (useless)
System.out.println(optionalNotEmpty.orElse(getDefaultValue()));
// orElseGet: getDefaultValue not called (better solution)
System.out.println(optionalNotEmpty.orElseGet(OptionalExample::getDefaultValue));
}
public static String getDefaultValue() {
System.out.println("called");
return "default value";
}
输出:
called
StringVal
StringVal
我想了解 Optional<T>.orElse()
and Optional<T>.orElseGet()
方法之间的区别。
orElse()
方法的描述是 "Return the value if present, otherwise return other."
而 orElseGet()
方法的描述是 "Return the value if present, otherwise invoke other and return the result of that invocation."
orElseGet()
方法采用 Supplier 功能接口,该接口基本上不采用任何参数和 returns T
。
在什么情况下需要使用orElseGet()
?如果你有一个方法 T myDefault()
你为什么不直接做 optional.orElse(myDefault())
而不是 optional.orElseGet(() -> myDefault())
呢?
orElseGet()
似乎没有将 lambda 表达式的执行推迟到稍后的某个时间或其他什么时间,那么它有什么意义呢? (我原以为如果它返回一个更安全的 Optional<T>
会更有用,它的 get()
永远不会抛出 NoSuchElementException
并且 isPresent()
总是 returns true.. .但显然不是,它只是 returns T
就像 orElse()
).
我还缺少其他一些区别吗?
以这两种情况为例:
Optional<Foo> opt = ...
Foo x = opt.orElse( new Foo() );
Foo y = opt.orElseGet( Foo::new );
如果opt
不包含值,两者确实是等价的。但是如果 opt
包含一个值,将创建多少 Foo
个对象?
P.s.: 当然,在这个例子中,差异可能无法衡量,但是如果您必须从远程 Web 服务获取默认值,或者从一个数据库,一下子就变得很重要了。
我来到这里是为了解决 Kudo 提到的问题。
我正在为其他人分享我的经验。
orElse
,或者orElseGet
,就是这个问题:
static String B() {
System.out.println("B()...");
return "B";
}
public static void main(final String... args) {
System.out.println(Optional.of("A").orElse(B()));
System.out.println(Optional.of("A").orElseGet(() -> B()));
}
打印
B()...
A
A
orElse
计算 B() 的值与可选值相互依赖。因此,orElseGet
是懒惰的。
我想说 orElse
和 orElseGet
之间的最大区别在于我们想要评估某些东西以获得 else
条件下的新值。
考虑这个简单的例子 -
// oldValue is String type field that can be NULL
String value;
if (oldValue != null) {
value = oldValue;
} else {
value = apicall().value;
}
现在让我们将上面的示例转换为使用 Optional
以及 orElse
、
// oldValue is Optional type field
String value = oldValue.orElse(apicall().value);
现在让我们将上面的示例转换为使用 Optional
以及 orElseGet
、
// oldValue is Optional type field
String value = oldValue.orElseGet(() -> apicall().value);
当调用 orElse
时,apicall().value
被评估并传递给方法。而在 orElseGet
的情况下,仅当 oldValue
为空时才会进行评估。 orElseGet
允许延迟计算。
简答:
- orElse() 将始终调用给定函数,无论您是否需要,无论
Optional.isPresent()
值如何 - orElseGet() 只会在
Optional.isPresent() == false
时调用给定的函数
在实际代码中,当所需资源获取的成本很高时,您可能需要考虑第二种方法。
// Always get heavy resource
getResource(resourceId).orElse(getHeavyResource());
// Get heavy resource when required.
getResource(resourceId).orElseGet(() -> getHeavyResource())
有关更多详细信息,请考虑以下使用此函数的示例:
public Optional<String> findMyPhone(int phoneId)
区别如下:
X : buyNewExpensivePhone() called
+——————————————————————————————————————————————————————————————————+——————————————+
| Optional.isPresent() | true | false |
+——————————————————————————————————————————————————————————————————+——————————————+
| findMyPhone(int phoneId).orElse(buyNewExpensivePhone()) | X | X |
+——————————————————————————————————————————————————————————————————+——————————————+
| findMyPhone(int phoneId).orElseGet(() -> buyNewExpensivePhone()) | | X |
+——————————————————————————————————————————————————————————————————+——————————————+
当optional.isPresent() == false
时,两种方式没有区别。但是,当optional.isPresent() == true
时,orElse()
不管你想不想,总是调用后面的函数。
最后使用的测试用例如下:
结果:
------------- Scenario 1 - orElse() --------------------
1.1. Optional.isPresent() == true (Redundant call)
Going to a very far store to buy a new expensive phone
Used phone: MyCheapPhone
1.2. Optional.isPresent() == false
Going to a very far store to buy a new expensive phone
Used phone: NewExpensivePhone
------------- Scenario 2 - orElseGet() --------------------
2.1. Optional.isPresent() == true
Used phone: MyCheapPhone
2.2. Optional.isPresent() == false
Going to a very far store to buy a new expensive phone
Used phone: NewExpensivePhone
代码:
public class TestOptional {
public Optional<String> findMyPhone(int phoneId) {
return phoneId == 10
? Optional.of("MyCheapPhone")
: Optional.empty();
}
public String buyNewExpensivePhone() {
System.out.println("\tGoing to a very far store to buy a new expensive phone");
return "NewExpensivePhone";
}
public static void main(String[] args) {
TestOptional test = new TestOptional();
String phone;
System.out.println("------------- Scenario 1 - orElse() --------------------");
System.out.println(" 1.1. Optional.isPresent() == true (Redundant call)");
phone = test.findMyPhone(10).orElse(test.buyNewExpensivePhone());
System.out.println("\tUsed phone: " + phone + "\n");
System.out.println(" 1.2. Optional.isPresent() == false");
phone = test.findMyPhone(-1).orElse(test.buyNewExpensivePhone());
System.out.println("\tUsed phone: " + phone + "\n");
System.out.println("------------- Scenario 2 - orElseGet() --------------------");
System.out.println(" 2.1. Optional.isPresent() == true");
// Can be written as test::buyNewExpensivePhone
phone = test.findMyPhone(10).orElseGet(() -> test.buyNewExpensivePhone());
System.out.println("\tUsed phone: " + phone + "\n");
System.out.println(" 2.2. Optional.isPresent() == false");
phone = test.findMyPhone(-1).orElseGet(() -> test.buyNewExpensivePhone());
System.out.println("\tUsed phone: " + phone + "\n");
}
}
考虑以下代码:
import java.util.Optional;
// one class needs to have a main() method
public class Test
{
public String orelesMethod() {
System.out.println("in the Method");
return "hello";
}
public void test() {
String value;
value = Optional.<String>ofNullable("test").orElseGet(this::orelesMethod);
System.out.println(value);
value = Optional.<String>ofNullable("test").orElse(orelesMethod());
System.out.println(value);
}
// arguments are passed using the text field below this editor
public static void main(String[] args)
{
Test test = new Test();
test.test();
}
}
如果我们这样得到value
:Optional.<String>ofNullable(null)
,orElseGet()和orElse()没有区别,但是如果我们这样得到value
:Optional.<String>ofNullable("test")
、orelesMethod()
在 orElseGet()
中不会被调用,但在 orElse()
中会被调用
下面的例子可以证明两者的区别:
String destroyTheWorld() {
// destroy the world logic
return "successfully destroyed the world";
}
Optional<String> opt = Optional.of("Save the world");
// we're dead
opt.orElse(destroyTheWorld());
// we're safe
opt.orElseGet(() -> destroyTheWorld());
答案也出现在文档中。
public T orElseGet(Supplier<? extends T> other)
:
Return the value if present, otherwise invoke other and return the result of that invocation.
如果 Optional
存在,Supplier
将不会被调用 。然而,
Return the value if present, otherwise return other.
如果 other
是 returns 字符串的方法,它将被调用,但如果 Optional
存在,则不会返回它的值。
差异非常细微,如果您不注意,就会以错误的方式使用它。
了解 orElse()
和 orElseGet()
之间区别的最佳方法是,如果 Optional<T>
为 null[=,则 orElse()
将始终执行44=]或者不是,但是orElseGet()
只会在Optional<T>
为null时执行。
字典中orElse的意思是:-当某物不存在时执行该部分,但这里矛盾,见下文示例:
Optional<String> nonEmptyOptional = Optional.of("Vishwa Ratna");
String value = nonEmptyOptional.orElse(iAmStillExecuted());
public static String iAmStillExecuted(){
System.out.println("nonEmptyOptional is not NULL,still I am being executed");
return "I got executed";
}
Output: nonEmptyOptional is not NULL,still I am being executed
Optional<String> emptyOptional = Optional.ofNullable(null);
String value = emptyOptional.orElse(iAmStillExecuted());
public static String iAmStillExecuted(){
System.out.println("emptyOptional is NULL, I am being executed, it is normal as
per dictionary");
return "I got executed";
}
Output: emptyOptional is NULL, I am being executed, it is normal as per dictionary
For
orElseGet()
, The method goes as per dictionary meaning, TheorElseGet()
part will be executed only when the Optional is null.
基准:
+--------------------+------+-----+------------+-------------+-------+
| Benchmark | Mode | Cnt | Score | Error | Units |
+--------------------+------+-----+------------+-------------+-------+
| orElseBenchmark | avgt | 20 | 60934.425 | ± 15115.599 | ns/op |
+--------------------+------+-----+------------+-------------+-------+
| orElseGetBenchmark | avgt | 20 | 3.798 | ± 0.030 | ns/op |
+--------------------+------+-----+------------+-------------+-------+
Remarks:
orElseGet()
has clearly outperformedorElse()
for our particular example.
希望它消除了像我这样想要非常基本的地面示例的人的疑虑:)
首先检查两个方法的声明。
1) OrElse: 执行逻辑并将结果作为参数传递。
public T orElse(T other) {
return value != null ? value : other;
}
2) OrElseGet: 如果可选中的值为空则执行逻辑
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操作DB调用,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()? 当默认值是某个常量对象枚举时,更喜欢使用 orElse。在上述所有情况下,我们可以使用 Optional.orElseGet()(仅当 Optional 包含空值时才执行)而不是 Optional.orElse()。为什么??在 orElse 中,我们传递默认结果值,但在 orElseGet 中,我们传递 Supplier 并且 Supplier 的方法仅在 Optional 中的值为 null 时执行。
要点:
- 如果包含任何日志语句,请不要使用“Optional.orElse”。
- 如果包含时间密集型逻辑,请不要使用“Optional.orElse”。
- 如果它正在改变某些对象状态,请不要使用“Optional.orElse”。
- 如果我们必须 return 一个常数,枚举,请使用“Optional.orElse”。
- 第1,2点和第3点提到的情况更喜欢“Optional.orElseGet”
我在第 2 点(“可选。map/Optional.orElse”!=“if/else”)我的中型博客中对此进行了解释。 Use Java8 as a programmer not as a coder
它们都习惯于return一个Optional的默认值,但是如果使用一个方法来产生默认值:
- orElse:总是执行该方法,如果 Optional 不为空
- orElseGet:仅当 Optional 为空时执行它 (+ Performance!)
查看此示例(class 可选示例):
public static void main(String[] args) {
Optional<String> optionalNotEmpty = Optional.of("StringVal");
// orElse: getDefaultValue called (useless)
System.out.println(optionalNotEmpty.orElse(getDefaultValue()));
// orElseGet: getDefaultValue not called (better solution)
System.out.println(optionalNotEmpty.orElseGet(OptionalExample::getDefaultValue));
}
public static String getDefaultValue() {
System.out.println("called");
return "default value";
}
输出:
called
StringVal
StringVal