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

时间:2019-06-24 07:36:28

标签: java

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

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

第2种情况中,您将获得带有已加载值的Optional(从getLoadedPoJo获得),并且还将执行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;
}

当前输出为:

  

执行getNullPoJo

     

执行getDefaultPoJo

     

pojo1默认设置

     

执行getLoadedPoJo

     

执行getDefaultPoJo

     

pojo2已加载

我的预期输出是:

  

执行getNullPoJo

     

执行getDefaultPoJo

     

pojo1默认设置

     

执行getLoadedPoJo

     

pojo2已加载

我不希望在案例2

中调用getDefaultPoJo

3 个答案:

答案 0 :(得分:17)

orElseGet()不为空时,使用getDefaultPoJo()避免求值Optional

PoJo poJo1=getNullPoJo().orElseGet(() -> getDefaultPoJo());
PoJo poJo2=getLoadedPoJo().orElseGet(() -> getDefaultPoJo());

答案 1 :(得分:13)

getNullPoJo().orElse(getDefaultPoJo());

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

1) getNullPoJo()
2) r = getDefaultPoJo()
3) orElse(r)  

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

通常,您会看到

.orElse(null);
.orElse(defaultValue);

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

另一方面,我们写

.orElseGet(() -> generateDefaultValue());
.orElseGet(() -> calculateDefaultOutcome());

其中generateDefaultValuecalculateDefaultOutcome是确实执行某些计算的方法(密集的计算或直到您需要的时候才希望执行的计算)。

比较

.orElseGet(() -> createDefaultPoJo());
.orElse(DEFAULT_POJO);

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

答案 2 :(得分:5)

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

Difference between `Optional.orElse()` and `Optional.orElseGet()`

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