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