`Optional.orElse()`和`Optional.orElseGet()`之间的区别
我想了解Optional<T>.orElse()
和Optional<T>.orElseGet()
方法之间的区别。
orElse()
方法的描述是“返回值如果存在,否则返回其他”。
而orElseGet()
方法的描述是“返回值,如果存在,否则调用其他值并返回该调用的结果”。
orElseGet()
方法采用供应商function接口,基本上不采用任何参数并返回T
在哪种情况下你需要使用orElseGet()
? 如果你有一个方法T myDefault()
为什么你不只是做optional.orElse(myDefault())
而不是optional.orElseGet(() -> myDefault())
?
orElseGet()
似乎并没有推迟lambdaexpression式的执行到某个更晚的时间或什么,所以它有什么意义呢? (我会认为它会更有用,如果它返回一个更安全的Optional<T>
其get()
永远不会抛出一个NoSuchElementException
和isPresent()
总是返回true …但显然它不是,它只是返回T
like orElse()
)。
还有一些其他的差异我失踪了吗?
采取这两种情况:
Optional<Foo> opt = ... Foo x = opt.orElse( new Foo() ); Foo y = opt.orElseGet( Foo::new );
如果opt
不包含一个值,那么两者确实是等价的。 但是,如果opt
包含一个值,将创build多less个Foo
对象?
Ps:当然在这个例子中差别可能不会被测量,但是如果你必须从远程Web服务或者从数据库中获得你的默认值,它突然变得非常重要。
我到达这里是为了解决工藤所提到的问题。
我为别人分享我的经验。
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
我会说,当我们想评估一些东西来获得else
条件下的新值时, orElse
和orElseGet
之间最大的区别。
考虑这个简单的例子 –
// oldValue is String type field that can be NULL String value; if (oldValue != null) { value = oldValue; } else { value = apicall().value; }
现在,让我们将上面的示例与orElse
一起使用orElse
,
// oldValue is Optional type field String value = oldValue.orElse(apicall().value);
现在让我们将上面的例子与orElseGet
一起使用orElseGet
,
// oldValue is Optional type field String value = oldValue.orElseGet(() -> apicall().value);
当调用orElse
, apicall().value
被计算并传递给方法。 而在orElseGet
的情况下,只有在oldValue
为空时orElseGet
进行评估。 orElseGet
允许懒惰评估。