`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允许懒惰评估。