Dimitriye98
Dimitriye98

Reputation: 207

Type mismatch with lambda

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

Answers (1)

Radiodef
Radiodef

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

Related Questions