`Optional.orElse()`和`Optional.orElseGet()`之间的区别

问题

我试图理解Optional<T>.orElse()Optional<T>.orElseGet()方法之间的区别。

orElse()方法的描述是"如果存在则返回值,否则返回其他值"。

虽然,对orElseGet()方法的描述是"如果存在则返回值,否则调用other并返回该调用的结果"。

orElseGet()方法采用供应商功能接口,基本上不接受任何参数并返回T

在哪种情况下你需要使用orElseGet()?如果你有方法T myDefault()为什么你不会只做optional.orElse(myDefault())而不是optional.orElseGet(() -> myDefault())

似乎并不是因为将lambda表达式的执行推迟到以后的某个时间或某事,所以它有什么意义呢? (我本以为如果它返回更安全Optional<T>whoseget()则抛出aNoSuchElementExceptionisPresent()always返回true会更有用...但显然它不是,它只返回3138047575像orElse())。

我还缺少其他一些差异吗?


#1 热门回答(99 赞)

采取以下两种情况:

Optional<Foo> opt = ...
Foo x = opt.orElse( new Foo() );
Foo y = opt.orElseGet( Foo::new );

如果opt不包含值,则两者确实等价。但ifopt确实有一个值,那么将创建多少Foo个对象?
P.s。:当然在本例中,差异可能无法衡量,但如果你必须从远程Web服务或数据库获取默认值,则突然变得非常重要。


#2 热门回答(39 赞)

我到达这里是为了解决问题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

#3 热门回答(28 赞)

我想说当我们想要评估某些内容以获得else条件中的新值时,orElse和4889863942之间的最大区别。

考虑这个简单的例子 -

// oldValue is String type field that can be NULL
String value;
if (oldValue != null) {
    value = oldValue;
} else {
    value = apicall().value;
}

现在让我们将上面的例子转换为使用Optionalalong withorElse

// oldValue is Optional type field
String value = oldValue.orElse(apicall().value);

现在让我们将上面的例子转换为使用Optionalalong withorElseGet

// oldValue is Optional type field
String value = oldValue.orElseGet(() -> apicall().value);

调用orElse时,将评估apicall().value并将其传递给该方法。然而,在orElseGet的情况下,仅当oldValue为空时才会进行评估.orElseGet允许进行延迟评估。