Java Optional – orElse() vs orElseGet() – Java Optional – orElse() vs orElseGet()

最后修改: 2018年 5月 17日

1. Introduction


The API of Optional typically has two methods that can cause confusion: orElse() and orElseGet().

Optional的API通常有两个方法,会引起混淆。orElse() orElseGet()

In this quick tutorial, we’ll look at the difference between these two and explore when to use each one.


2. Signatures


First, let’s start with the basics by looking at their signatures:


public T orElse(T other)

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

Clearly, orElse() takes any parameter of a type T, whereas orElseGet() accepts a functional interface of type Supplier that returns an object of type T.

显然,orElse() 接受任何T类型的参数,orElseGet() 接受一个Supplier 类型的功能接口,返回T类型的对象。

Based on their Javadocs:


  • orElse(): returns the value if present, otherwise returns other
  • orElseGet(): returns the value if present, otherwise invokes other and returns the result of its invocation

3. Differences


It’s easy to be a bit confused by these simplified definitions, so let’s dig a little deeper and look at some actual usage scenarios.


3.1. orElse()

3.1. orElse()

Assuming we have our logger configured properly, let’s start with writing a simple piece of code:


String name = Optional.of("baeldung")

Notice that getRandomName() is a method which returns a random name from a List<String>of names:


public String getRandomName() {"getRandomName() method - start");
    Random random = new Random();
    int index = random.nextInt(5);"getRandomName() method - end");
    return names.get(index);

On executing our code, we’ll find the below messages printed in the console:


getRandomName() method - start
getRandomName() method - end

The variable name will hold “baeldung” at the end of the code execution.

变量name 将在代码执行结束时保持 “baeldung”

With it, we can easily infer that the parameter of orElse() is evaluated, even when having a non-empty Optional.


3.2. orElseGet()

3.2. orElseGet()

Now let’s try writing similar code using orElseGet():


String name = Optional.of("baeldung")
  .orElseGet(() -> getRandomName());

The above code won’t invoke the getRandomName() method.


Remember (from the Javadoc) that the Supplier method passed as an argument is only executed when an Optional value isn’t present.

记住(来自Javadoc),作为参数传递的Supplier方法只有在an Optional值不存在时才会执行。

Therefore, using orElseGet() for our case will save us the time involved in computing a random name.


4. Measuring Performance Impact


Now, to also understand the differences in performance, let’s use JMH and see some actual numbers:


public String orElseBenchmark() {
    return Optional.of("baeldung").orElse(getRandomName());

And orElseGet():


public String orElseGetBenchmark() {
    return Optional.of("baeldung").orElseGet(() -> getRandomName());

While executing our benchmark methods, we get:


Benchmark           Mode  Cnt      Score       Error  Units
orElseBenchmark     avgt   20  60934.425 ± 15115.599  ns/op
orElseGetBenchmark  avgt   20      3.798 ±     0.030  ns/op

As we can see, the performance impact might be substantial, even for such a simple use-case scenario.


The numbers above might slightly vary; however, orElseGet() has clearly outperformed orElse() for our particular example.


After all, orElse() involves the computation of the getRandomName() method for each run.

毕竟,orElse() 涉及到每次运行的getRandomName() 方法的计算。

5. What’s Important?


Apart from the performance aspects, other factors worth considering include:


  • What if the method would execute some additional logic? E.g. making some DB inserts or updates
  • Even when we assign an object to the orElse() parameter, we’re still creating “Other” object for no reason:
    String name = Optional.of("baeldung").orElse("Other")

That’s why it’s important for us to make a careful decision between orElse() and orElseGet() depending on our needs. By default, it makes more sense to use orElseGet() every time, unless the default object is already constructed and directly accessible.


6. Conclusion


In this article, we learned the nuances between the Optional orElse() and OrElseGet() methods. We also discussed how such simple concepts can sometimes have a deeper meaning.

在这篇文章中,我们了解了Optional orElse() OrElseGet() 方法之间的细微差别。我们还讨论了这样简单的概念有时会有更深的含义。

As always, the complete source code can be found over on Github.