foreach/filter/map/reduce on Iterable & Iterators
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Thu Sep 15 05:36:25 PDT 2011
On 15/09/11 12:56, Colin Decker wrote:
> "? extends U" isn't necessary for map. All that allows is assigning what is
> really, say, an Iterable<Integer> to Iterable<Number> or Iterable<Object>
> without casting, which doesn't help anything.
>
I think they are referring to changing the signature of Collection.map
(and other related methods) from this:
<U> Iterable<U> map(Mapper<T, U> mapper) ...
to this:
<U> Iterable<U> map(Mapper<? super T, ? extends U> mapper) ...
Now, while this case the '? extends' is conceptually correct, I kinda
agree that the outcome won't be too different should the '? extends' be
omitted. Since U is a method type-parameter (whose bound is Object -
unrelated to T), that means that most of the times type-inference will
be able to infer the right type for U; for example:
Mapper<Object, Object> moo;
Mapper<Number, Number> mnn;
Mapper<Integer, Integer> mii;
List<Integer> li = ...
li.map(moo) // U == Object
li.map(mnn) // U == Number
li.map(mii) // U == Integer
The above will work regardless of whether you put the '? extends'
wildcard or not. Where things will be different is when type-parameters
are explicitly specified:
li.<Object>map(mii) // ok with wildcards / error w/o wildcards (U == Object)
li.<Number>map(mii) // ok with wildcards / error w/o wildcards (U == Number)
Note that the above pattern might be common if i.e. you want to assign
the result of the map operation to a type that is less specific than the
type of the mapper. I.e.
List<Object> lo = li.map(mii) // U == Integer, type-mismatch,
List<Integer> not compatible with List<Object>
List<Object> lo = li.<Object>map(mii) // ok
Maurizio
More information about the lambda-dev
mailing list