【问题标题】:When to use Optional.orElse() rather than Optional.orElseGet() [duplicate]何时使用 Optional.orElse() 而不是 Optional.orElseGet() [重复]
【发布时间】:2019-01-09 02:13:31
【问题描述】:

我已经阅读了关于Optional.orElse()Optional.orElseGet() 之间区别的question 的答案。

由于惰性评估,orElseGet() 似乎总是比 orElse() 更有效,即使在对像这样非常简单的示例进行基准测试时也明显可见(参见第 4 部分):https://www.baeldung.com/java-optional-or-else-vs-or-else-get

那么,有没有使用orElse 而不是orElseGet 更好的用例?

【问题讨论】:

  • 也许 Optional 为空的可能性更高。
  • 就像链接所说的:“默认情况下,每次使用 orElseGet() 会更有意义除非默认对象已经构建并且可以直接访问。
  • 当您已经承担了创建对象的成本时,这才有意义。否则,您可以将对象创建延迟到实际需要为止。

标签: java java-8 optional


【解决方案1】:
  1. 在大多数情况下,您在使用 orElse 时输入较少,因为它比 orElseGet 短,并且比较它们的签名:

orElse(T other)
orElseGet(Supplier<? extends T> other)

Supplier&lt;? extends T&gt; other 很可能比 T other 长。如果性能不是那么重要,您可以选择少输入。程序员的努力也很重要:-) 例如,比较:

orElseGet(() -> 1)
orElse(1)
  1. 正如您的链接所提到的:

默认情况下,每次都使用 orElseGet() 更有意义,除非 默认对象已构建并可直接访问。

【讨论】:

  • 第一部分并没有真正回答这个问题,只是说“它不那么冗长”,这不是一个很好的理由。第二部分是关键。
【解决方案2】:

当你知道你需要回退到一个常量(甚至是一个已经创建的对象)来默认使用时,它可能更可取的主要用例之一。我的意思是,只是比较一下这有多糟糕:

int first = Stream.of(1,3,5).filter(i->i%2==0).findFirst().orElseGet(new Supplier<Integer>() {
    @Override
    public Integer get() {
        return 1;
    }
});

或其 lambda 表示

int first = Stream.of(1,3,5).filter(i->i%2==0).findFirst().orElseGet(() -> 1);

相比是多余的
int first = Stream.of(1,3,5).filter(i->i%2==0).findFirst().orElse(1);

【讨论】:

  • 第一句话是“何时使用”它的实际问题的正确答案的关键(我认为 lambda 的东西妨碍了)。如果您想在可选项为空时使用常量或已经创建的对象,那么 .orElse() 是正确的方法。
【解决方案3】:

以下是简答,更详细的答案请查看my stackoverflow answer here

  • orElse() 将始终调用给定函数,无论您是否愿意,无论Optional.isPresent() 值如何
  • orElseGet() 只会在Optional.isPresent() == false 时调用给定的函数

由于第一种方法总能获得资源,当所需资源获取成本高时,您可能需要考虑第二种方法。

【讨论】:

  • 那么为什么不标记为重复呢?
猜你喜欢
  • 2017-10-30
  • 1970-01-01
  • 2016-01-15
  • 1970-01-01
  • 2010-10-22
  • 2012-05-16
  • 1970-01-01
  • 2012-07-11
相关资源
最近更新 更多