The return type of map
is Optional <U>
, so to get a real value you should call for orElse
with the return type of T
.
This is the toString
implementation if the Optional
:
@Override
public String toString() {
return value != null
? String.format("Optional[%s]", value)
: "Optional.empty";
}
So, calling toString
you'll never get the real value, but a value wrapped to Optional
, while orElse
will return you the default provided value.
Let's see the difference:
Integer i = 4;
String s = Optional.ofNullable(i)
.map(Objects::toString)
.toString();
System.out.println(s);
Output:
Optional[4]
With null
:
Integer i = null;
String s = Optional.ofNullable(i)
.map(Objects::toString)
.toString();
System.out.println(s);
Output:
Optional.empty
While using orElse
:
Integer i = null;
String s = Optional.ofNullable(i)
.map(Objects::toString)
.orElse("None");
System.out.println(s);
Output:
None
So you can see that there are different purposes of these methods.
And the answer to your comment:
"Is there a way to call get() and also call orElse() in the same chain?"
Integer i = 10;
String s = Optional.ofNullable(i)
.map(Objects::toString)
.orElse("None");
System.out.println(s);
Output:
10
You don't need to call get
explicitly, the value will be fetched if not null
;
/**
* If a value is present, returns the value, otherwise returns
* {@code other}.
*
* @param other the value to be returned, if no value is present.
* May be {@code null}.
* @return the value, if present, otherwise {@code other}
*/
public T orElse(T other) {
return value != null ? value : other;
}