何时使用 Optional.orElse() 而不是 Optional.orElseGet()

11

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

似乎orElseGet()总是比orElse()更有效率,因为它使用了惰性求值,即使在基准测试非常简单的示例时也明显可见(参见部分4):https://www.baeldung.com/java-optional-or-else-vs-or-else-get

那么,在什么情况下最好使用orElse而不是orElseGet?


如果 Optional 为空的可能性更高,那么可能。 - jcal
3
就像链接所说:“默认情况下,除非默认对象已经构造并可以直接访问,否则每次使用orElseGet()更有意义。” - Jorn Vernee
只有在你已经承担了创建对象的成本时,这种做法才是有意义的。否则,你可以推迟对象的创建,直到它真正需要为止。 - John
3个回答

12
  1. 在大多数情况下,使用orElse比使用orElseGet更短,因为它的签名比较简洁:
orElse(T other)
orElseGet(Supplier<? extends T> other)

Supplier<? extends T> otherT other 更长。如果性能不是很重要,您可以选择输入更少的内容。程序员的努力也很重要 :-) 例如,比较一下:

orElseGet(() -> 1)
orElse(1)

作为您提供的链接已经提到的:默认情况下,除非默认对象已经被构造并可以直接访问,否则每次使用orElseGet()更有意义。

第一部分并没有真正回答问题,除了说“它更简洁”,这不是一个很好的理由。第二部分才是关键。 - Ted M. Young

3

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

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);

2
第一句话是回答“何时使用”实际问题的关键(我认为lambda可能会妨碍理解)。如果您有一个常量或已创建的对象,并且希望在可选项为空时使用它,则.orElse()是正确的选择。 - Ted M. Young

2
以下是简短回答,如需更详细的答案,请查看我的stackoverflow答案
  • orElse()无论Optional.isPresent()的值为何,都会调用给定的函数。
  • orElseGet()只有在Optional.isPresent() == false时才会调用给定的函数。

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


那为什么不标记为重复? - Jean-François Fabre

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接