简体   繁体   中英

Why Iterator<Entry<Integer, Double> cannot be converted to Iterator<Entry<? extends Integer, ? extends Double>>

I have the sample code below attempting to construct an immutable map out of an iterable:

ImmutableList<Entry<Integer, Double>> list = ImmutableList.of(
    new AbstractMap.SimpleEntry<Integer, Double>(4, 2d),
    new AbstractMap.SimpleEntry<Integer, Double>(16, 4d));
ImmutableMap.<Integer, Double>builder().putAll(list); // No error
ImmutableMap.<Integer, Double>builder().putAll(() -> list.stream().iterator()); // Error - cannot convert type...

I am getting the error Bad return type in lambda expression: Iterator<Entry<Integer, Double>> cannot be converted to Iterator<Entry<? extends Integer, ? extends Double>> Bad return type in lambda expression: Iterator<Entry<Integer, Double>> cannot be converted to Iterator<Entry<? extends Integer, ? extends Double>> Bad return type in lambda expression: Iterator<Entry<Integer, Double>> cannot be converted to Iterator<Entry<? extends Integer, ? extends Double>> . From my understanding this should be valid because Integer is a valid upper bound of Integer, and Double is a valid upper bound of Double. What is the problem here and how can I fix specifically the iterator code?

I need to fix the iterator code in particular since I am trying to transform another collection into a map like below. I am using guava on android so do not have access to the default guava collect() methods (though I think I can implement them manually if there is really no other way to do this).

ImmutableList<Integer> numberList = ImmutableList.of(2,4,8,12,16,24,32);
ImmutableMap.<Integer, Double>builder().putAll(() -> 
   numberList.stream().map(num -> 
       (Entry<Integer, Double>) new AbstractMap.SimpleEntry<Integer, Double>(num, Math.sqrt(num))).iterator());

Oh boy, this one is ugly.

You're right that Entry<? extends Integer, ? extends Double> Entry<? extends Integer, ? extends Double> Entry<? extends Integer, ? extends Double> is a "subtype" of Entry<Integer, Double> (I think it's not technically called a subtype, but is effectively one). But, as you may know, Iterator<Subtype> is not a subtype of Iterator<Supertype> . Instead you have to do Iterator<? extends Subtype> Iterator<? extends Subtype> .

So you'd need to add just one more ? extends ? extends in there:

Iterator<? extends Entry<? extends Integer, ? extends Double>>
         ^^^^^^^^^

I'm not sure offhand what the best way to do that is, though.

Integer is not a valid upper bound of Integer, you can't extend class A from class A. For example yout can't write this: Public class Actor extends Actor{ } So to solve your problem make Number instead Integer like this Iterator<Entry<? extends Number, ?extends Number>>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM