Reputation: 207
So the following code:
scoreCombiner = (Collection<ScoreContainer> subScores) -> subScores.parallelStream()
.mapToInt(ScoreContainer::getScore)
.reduce((a, b) -> a + b);
where scoreCombiner
is a field declared as
private final ToIntFunction<? super List<? super ScoreContainer>> scoreCombiner;
is giving me the error Type mismatch: cannot convert from ToIntFunction<Collection<ScoreContainer>> to ToIntFunction<? super List<? super ScoreContainer>>
which I can't understand. Collection is definitely a super-type of List, and ScoreContainer is, of course, a super-type of itself. Any help would be appreciated.
Upvotes: 2
Views: 459
Reputation: 37875
The ? super List
is fine in this context.
For example this would compile:
ToIntFunction<? super List<?>> f = ( (Collection<?> c) -> 0 );
A ToIntFunction<? super List<?>>
is a ToIntFunction
that consumes a List<?>
, which a ToIntFunction<Collection<?>>
does.
The issue is the typing of the List/Collection. Recall now again, a List<? super ScoreContainer>
is any List that accepts a ScoreContainer. So the trouble here is that an IntFunction<? super List<? super ScoreContainer>>
accepts any List that accepts a ScoreContainer. So for example, you should be able to pass it a Collection<Object>
.
You could only assign a lambda such as
... = (Collection<? super ScoreContainer> subScores) -> subScores...();
But the Collection your lambda is expecting is really a producer. You are expecting it to produce ScoreContainers (which you call getScore
on). So you should be bounded by extends
.
ToIntFunction<? super List<? extends ScoreContainer>> scoreCombiner;
... = (Collection<? extends ScoreContainer> subScores) -> subScores...();
Upvotes: 1