orElse的Java可选工作与其他情况不同

Kis*_*ran 17 java

在Optional中,当调用optional.orElse方法时,无论是否存在元素,orElse部分是否被执行,它都不会表现为if else条件。

在下面的代码中,如果您在案例1中看到,则getNullPoJo和getDefaultPoJo都将执行,因为getNullPoJo将返回空

情况2中,您将从加载的值(从getLoadedPoJo)获得一个Optional并执行getDefaultPoJo

我只是想了解optional.orElse的工作方式。

public static void main (String [] a) {
    PoJo poJo1=getNullPoJo().orElse(getDefaultPoJo());//Case 1
    System.out.println("pojo1 Got "+poJo1.getVariable());
    PoJo poJo2=getLoadedPoJo().orElse(getDefaultPoJo());//Case 2
    System.out.println("pojo2 Got "+poJo2.getVariable());
}

private static Optional<PoJo> getNullPoJo() {
    System.out.println("Executing getNullPoJo");
    Optional<PoJo> optional=Optional.empty();
    return optional;
}

private static Optional<PoJo> getLoadedPoJo() {
    System.out.println("Executing getLoadedPoJo");
    PoJo poJo =new PoJo();
    poJo.setVariable("Loaded");
    Optional<PoJo> optional=Optional.of(poJo);
    return optional;
}

private static PoJo getDefaultPoJo() {
    System.out.println("Executing getDefaultPoJo");
    PoJo poJo =new PoJo();
    poJo.setVariable("Default");
    return poJo;
}
Run Code Online (Sandbox Code Playgroud)

当前输出为:

执行getNullPoJo

执行getDefaultPoJo

pojo1默认

执行getLoadedPoJo

执行getDefaultPoJo

pojo2已加载

我的预期输出是:

执行getNullPoJo

执行getDefaultPoJo

pojo1默认

执行getLoadedPoJo

pojo2已加载

案例2中,我不希望调用getDefaultPoJo

Era*_*ran 17

使用orElseGet()以避免评估getDefaultPoJo()Optional不为空:

PoJo poJo1=getNullPoJo().orElseGet(() -> getDefaultPoJo());
PoJo poJo2=getLoadedPoJo().orElseGet(() -> getDefaultPoJo());
Run Code Online (Sandbox Code Playgroud)

  • @Caleth如果`getDefaultPoJo`引用了该方法就没有任何意义...您是说方法引用`orElseGet(ClassWhereTheMethodDefined :: getDefaultPoJo)`吗? (2认同)

And*_*lko 13

getNullPoJo().orElse(getDefaultPoJo());
Run Code Online (Sandbox Code Playgroud)

这是一个方法链,无论底层API应该如何工作,该链中的每个方法都将被执行。

1) getNullPoJo()
2) r = getDefaultPoJo()
3) orElse(r)  
Run Code Online (Sandbox Code Playgroud)

为了执行一种方法,必须评估其实际参数。要调用orElse(getDefaultPoJo()),也getDefaultPoJo()必须被调用。这就是您获得超出预期的收益的原因。

通常,您会看到

.orElse(null);
.orElse(defaultValue);
Run Code Online (Sandbox Code Playgroud)

其中nulldefaultValue是不需要任何计算的预定义值。

另一方面,我们写

.orElseGet(() -> generateDefaultValue());
.orElseGet(() -> calculateDefaultOutcome());
Run Code Online (Sandbox Code Playgroud)

其中,generateDefaultValuecalculateDefaultOutcome是执行某些计算的方法(密集的或我们不希望在适当的时候[您的情况]下才执行的方法)。

比较,

.orElseGet(() -> createDefaultPoJo());
.orElse(DEFAULT_POJO);
Run Code Online (Sandbox Code Playgroud)

其中DEFAULT_POJO是在此方法调用之前初始化的变量,并且createDefaultPoJo()是一个在每次调用时创建默认实例的方法。


ItF*_*eak 5

输出正确,Optional.orElse()将始终执行else-action。(您提供的表达式)对所需的输出使用orElseGet()-仅在Optional.isPresent == false-时调用函数:

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

https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html#orElseGet-java.util.function.Supplier-