`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()永远不会抛出一个NoSuchElementExceptionisPresent()总是返回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服务或者从数据库中获得你的默认值,它突然变得非常重要。

我到达这里是为了解决工藤所提到的问题。

我为别人分享我的经验。

orElseorElseGet ,这是一个问题:

 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条件下的新值时, orElseorElseGet之间最大的区别。

考虑这个简单的例子 –

 // 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); 

当调用orElseapicall().value被计算并传递给方法。 而在orElseGet的情况下,只有在oldValue为空时orElseGet进行评估。 orElseGet允许懒惰评估。