While reading the Stream interface source code I found this method signature:
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
I wonder why the input type of mapper is ? super T while the output type is ? extends R, why not use ? extends for both?
In generic code, the question mark (?), called the wildcard, represents an unknown type. The wildcard can be used in a variety of situations: as the type of a parameter, field, or local variable; sometimes as a return type (though it is better programming practice to be more specific).
If you just specify a type (class) as bounded parameter, only sub types of that particular class are accepted by the current generic class. These are known as bounded-types in generics in Java.
What is the difference between a wildcard bound and a type parameter bound? A wildcard can have only one bound, while a type parameter can have several bounds. A wildcard can have a lower or an upper bound, while there is no such thing as a lower bound for a type parameter.
Use an upper-bounded wild card only when values are to be retrieved and processed and the data structure (ArrayList) won't be changed. This means that the corresponding argument of a call on m2 can be an ArrayList whose elements are of any class that is Integer or a superclass of Integer, including Number and Object.
Consider you want to map a CharSequence to another CharSequence (thus T = R = CharSequence). Which functions will work for you?
Function<Object, String> fn1 = Object::toString;
Is it good for you? Yes, because it can take any CharSequence (which is also Object) and convert it to the String (which is also CharSequence).
Function<CharSequence, StringBuilder> fn2 = StringBuilder::new;
Is it good for you? Yes, because it can take any CharSequence and convert it to the StringBuilder (which is also CharSequence).
Function<String, String> fn3 = String::trim;
Is it good for you? No, because it cannot take any CharSequence, only some of them.
Thus you can see that first type argument must be CharSequence or any superclass, but second must be CharSequence or any subclass.
Because of PECS :) - Producer Extends, Consumer Super
Producer Extends - If you need a List to produce T values (you want to read Ts from the list), you need to declare it with ? extends T
Consumer Super - If you need a List to consume T values (you want to write Ts into the list), you need to declare it with ? super T
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