I need a clear explanation of this, even though I read this link on differences but no clear clarity. So can anyone explain to me on this in short with code?
-
What is not clear in the accepted answer? – Jens May 30 '17 at 11:41
-
I not got clear picture with that answer – TVK May 30 '17 at 11:43
-
Generally you can use one or the other as you like. – Ole V.V. May 30 '17 at 11:57
-
3If producing the value to return in the “orElse” case requires some computation, my taste would probably be for `orElseGet()` so that the computation is only performed when needed. If the computation has side effects, you should choose based on whether you want those sideeffects always or only when the object is needed. – Ole V.V. May 30 '17 at 11:59
-
1`orElse()` would be the natural choice in most situations. In our code base we use `orElse()` 31 times and `orElseGet()` 0 times at all. – Ole V.V. May 30 '17 at 12:04
-
3@OleV.V. I did the same thing just now :) one usage of `orElseGet` - the returned object comes from a database call. – Eugene May 30 '17 at 12:05
-
That’s certainly warranted! @Eugene Thanks for that stats. – Ole V.V. May 30 '17 at 12:06
-
Related: [Difference between `Optional.orElse()` and `Optional.orElseGet()`](https://stackoverflow.com/questions/33170109/difference-between-optional-orelse-and-optional-orelseget) – Ole V.V. Nov 11 '18 at 11:52
3 Answers
I think I am starting to understand your question. Execution order with Optional
can be different from what we are used to in procedural programming (the same is true for Java streams and other code using lambdas).
I will use the two examples from Eugene’s answer:
o1.orElse(new MyObject()); // 1055e4af
This is plain old Java: it’s a call to orElse()
taking new MyObject()
as argument. So the argument is evaluated first and a new MyObject
created. This is then passed to orElse()
. orElse()
looks to see whether a value is present in the Optional
; if so it returns that value (discarding the newly created object); if not, it returns the object given to it in the argument. This was the simpler example.
o1.orElseGet(() -> {
System.out.println("Should I see this");
return new MyObject();
});
Again we have a method call with one argument, and again the argument is evaluated first. The lambda is only created and passed as a supplier. The code inside { }
is not executed yet (you also see no Should I see this
in Eugene’s output). Again orElseGet
looks to see if there is a value present in the Optional
. If there is, the value is returned and the supplier we passed is ignored. If there isn’t, the supplier is invoked, the code inside { }
is executed to get the value to be returned from orElseGet()
.
In the first case, one may say that a MyObject
is created and wasted. In the second a Supplier
is created and wasted. What you get in return is terse and null-pointer safe code in both cases. So very often it’s not important which one you pick. If creating the MyObject
is costly or has unwanted side effects, you will of course want the second version where the object is only created when it is asked for, and is never wasted. Eugene in a comment mentions the case where the returned object comes from a database call. Database calls are usually time-consuming enough that you don’t want to make one for no purpose.

- 81,772
- 15
- 137
- 161
-
3
-
If Optional (o1) returns empty then "orElse" will also return empty ??? Like an following sample code String x =null; Optional
o1 = Optional.ofNullable(x); o1.orElse("po"); – TVK May 31 '17 at 05:59 -
Did you try it? Answer is no, in this case `orElse()` will return `"po"`. – Ole V.V. May 31 '17 at 06:23
-
-
Weird. Sounds like you have printed the `Optional` (invoking its `toString()`), not the return string from `orElse()`. – Ole V.V. May 31 '17 at 07:19
How about an example:
static class MyObject {
public MyObject() {
System.out.println("Creating one..." + this);
}
}
And some usage:
Optional<MyObject> o1 = Optional.of(new MyObject()); // 7382f612
o1.orElse(new MyObject()); // 1055e4af
o1.orElseGet(() -> {
System.out.println("Should I see this");
return new MyObject();
});
And some output:
Creating one... MyObject@7382f612
Creating one... MyObject@1055e4af
In case Optional
has a value; orElse
is still called but not used. On the contradictory orElseGet
is not called.
Consider the case when creating the object is expensive; which one you will use?
It's actually easier to understand I think if you look in the code:
public T orElseGet(Supplier<? extends T> supplier) {
return value != null ? value : supplier.get();
}

- 117,005
- 15
- 201
- 306
-
Just one confusion,,, at a time orElse and orElseGet will execute?? not as per above code – TVK May 30 '17 at 12:23
-
Am I the sole to whom _is still called but not used_ looks like a poor API design? What is the reason to call something but not use it? Is it similar to `finally` in `try-catch` expression? – Mike Jan 10 '19 at 09:30
-
@MikeB. how is that similar? `finally` is *always* called. Also how many times have you written `new HashMap<>()` for example to only add two entries to it for example - more space is reserved, but you are not using it. And most probably `orElse(new ArrayList<>())` would be cheaper that calling a `Supplier` that produces one. – Eugene Jan 13 '19 at 13:49
-
@Eugene, as far as I understand, `orElse()` is always called, no matter if the object to whom belongs `orElse()` is `null` or not `null`. – Mike Jan 13 '19 at 17:29
-
1@MikeB. now I get your point, yes `orElse` is always called; not sure if this is a bad API decision though. It is sometimes cheaper to create an Object and not use it, than defer to some method that might create it - and I really think this is the case here. – Eugene Jan 14 '19 at 10:24
As answered here, you might want to consider the second approach when the required resource is expensive to get.
// Always get heavy resource
getResource(resourceId).orElse(getHeavyResource());
// Get heavy resource when required.
getResource(resourceId).orElseGet(() -> getHeavyResource())

- 13,452
- 11
- 45
- 44