This is the implementation of map()
method:
public <U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent()) {
return empty();
} else {
return Optional.ofNullable(mapper.apply(value));
}
}
When I call map()
like this, what is the type of T
and U
? What is the type of wildcard (?
)? It is very confusing.
Optional<String> os1 = Optional.of("Optional String");
Optional<String> os2 = os1.map(s -> s.toUpperCase());
Javadoc statement says:
@param
<U>
is the type of the value returned from the mapping function.
Does "mapping function" mean map()
method or argument of the map()
?
Regardless if it's Stream
or Optional
, the purpose of the method map
which accepts Function<? super T, ? extends U>
is to map each input value T
to an output of the same or different type U
. The wildcard is used for extending the range of mapping possibilities.
Does "mapping function" mean
map()
method or argument of themap()
?
The "mapping function" is a T
-> U
mapping implementation of an anonymous class of the Function
interface which might be shortened with a lambda expression or a method reference.
In your sample, the T
and U
are both String
since you map the String
to its upper-case variation which is a String
again. It behaves the same like UnaryOperator<T>
a special case of Function<T, T>
which consumes and returns the same type.
On the other hand, if you map:
os1.map(s -> s.length())
T
is String
U
is Integer
since the method String::length
produces an integerYou might shorten the lambda with a method reference:
Optional<String> os2 = os1.map(String::toUpperCase);
... or better use both of the Optional
s together:
Optional<String> os1 = Optional.of("Optional String");
.map(String::toUpperCase);
Firstly, just to answer your question of:
Does "mapping function" mean map() method or argument of the map()?
This "mapping function" refers to the argument supplied to the map
method of the Optional<T>
type.
To make things easier to understand, just forget about the wildcard (?
) for a moment as we could do without its confusion and focus on the type T
and U
, the simplified version below:
public <U> Optional<U> map(Function<T, U> mapper) { ... }
T
represents any type of object as input and U
represents any type as output.Function<T, U> mapper
represents a function taking an object of type T
and returns a value of type U
Optional<U>
is an Optional encapsulating an object of type U
.You could visualize the mapper function as:
_ _ _ _ _ _ _ _ _
| |
| |
T ----->| logic | -----> U
| |
|_ _ _ _ _ _ _ _ _|
So, given the above visualisation and your example of:
Optional<String> os1 = Optional.of("Optional String");
Optional<String> os2 = os1.map(s -> s.toUpperCase());
The function passed to the map
method of the Optional
type (s -> s.toUpperCase()
) is Function<String, String> mapper
i.e. T
in the visualization above becomes String
and U
in the visualization above becomes String
i.e.
_ _ _ _ _ _ _ _ _
| |
| |
String -->| logic | ---> String
| |
|_ _ _ _ _ _ _ _ _|
So, when the above function is invoked by the map
method of the Optional type, it will perform some operation represented by the "logic" above in the visualization, in this specific case the logic is simply converting the input string to an uppercase string.
Once that is done, the map
method of the Optional<T>
type wraps that uppercase string into an Optional object hence it returns an Optional<String>
.
Seems to me you have a wrong src (with Javadoc) project of you JDK. Consider what the Oracle Docs about Optional in Java 8 says:
map(Function mapper)
If a value is present, apply the provided mapping function to it, and if the result is non-null, return an Optional describing the result.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With