【问题标题】:Parameter of Optional.orElse gets called even when Optional contains value [duplicate]即使 Optional 包含值 [重复],Optional.orElse 的参数也会被调用
【发布时间】:2018-03-31 12:10:35
【问题描述】:

以下代码打印:

should Not have called
hello world

为什么orElse 会被执行,即使我们有一个包含值的 Optional?

public static void main(String[] args){
    String o = Optional.ofNullable("world").map(str -> "hello" + str).orElse(dontCallMe());
    System.out.println(o);
}

private static String dontCallMe() {
    System.out.println("should Not have called");
    return "why god why";
}

【问题讨论】:

    标签: java java-8 optional


    【解决方案1】:

    orElse 方法looks like 这个:

    public T orElse(T other) {
       return value != null ? value : other;
    }
    

    这里没有任何复杂的逻辑。

    与任何方法一样,它将执行以下操作:

    • 获取传递给方法的所有参数的实际值(包括调用这些参数中的任何方法)。
    • 将这些参数传递给方法。
    • 执行方法。

    我们实际上不关心参数的值这一事实并没有改变这个过程(这正是语言的设计方式,无论好坏)。


    如果您不想调用参数中的方法,您可能正在寻找Optional.orElseGet

    这个:

    public static void main(String[] args){
        String o = Optional.ofNullable("world").map(str -> "hello" + str)
                       .orElseGet(() -> dontCallMe());
        System.out.println(o);
    }
    
    private static String dontCallMe() {
        System.out.println("should not have called");
        return "why oh why";
    }
    

    仅输出:

    helloworld
    

    这里的区别是我们传递给方法的东西 (Supplier) 将保持() -> dontCallMe(),它不会变成() -> "why oh why" - 只有当你调用get 时它才会真正评估正在发生的事情在那里,dontCallMe 确实被调用了。

    【讨论】:

    • 不错!建议 orElseGet 用于示例目的都很好,但我想添加更多内容。仅当要执行的操作计算量大时才应使用此方法,否则请使用 orElse。
    【解决方案2】:

    请,有人可以解释为什么orElse 正在执行事件 after map 将被执行以获得最终结果。

    使用orElse 方法,无论包装的值是否存在,都会创建默认对象。

    因此当你调用orElse中的函数dontCallMe()返回字符串值时; "should Not have called" 将打印到控制台。

    使用orElseGet 而不是orElse 将提供您期望的结果,尽管您应该只在默认值的创建计算成本很高或者您想确保当且仅当值时才使用此方法不存在(空的可选)在这种情况下是必要的。

    顺便说一句,这里不需要使用Optional.ofNullableOptional.of 方法更合适,因为前者应该在参数可以为空的情况下使用,而后者仅当参数不能为空时

    作为阅读,您可以在 baeldung 网站上查看这篇好帖子。

    Guide To Java 8 Optional

    【讨论】:

    • 要点是,在orElseGet 中,您提供了一个Supplier,它仅在需要时委托创建代码。另一个很好的例子是记录器
    猜你喜欢
    • 2021-02-08
    • 1970-01-01
    • 1970-01-01
    • 2015-03-15
    • 2019-10-21
    • 1970-01-01
    • 2011-07-27
    • 1970-01-01
    • 2015-03-01
    相关资源
    最近更新 更多