I have two Multimaps of Strings indexed by (i) Integers and (ii) Doubles and a routine to output lists of the Strings. 
public static void outputInteger(Multimap<Integer, String> map) {
    for (Integer key : map.keySet()) {
        Collection<String> strings = map.get(key);
        output(strings);
    }
}
public static void outputDouble(Multimap<Double, String> map) {
    for (Double key : map.keySet()) {
        Collection<String> strings = map.get(key);
        output(strings);
    }
}
I would like to combine these into a single routine using Number as the superclass of Integer and Double
public static void outputNumber(Multimap<? extends Number, String> map) {
    for (Number key : map.keySet()) {
        Collection<String> ids = map.get(key); //** 
    }
}
but the asterisked line does not compile
The method get(capture#5-of ? extends Number) in the type 
Multimap<capture#5-of ? extends Number,String> is not 
applicable for the arguments (Number)
How do I tackle this?
The declaration
Multimap<? extends Number, String> map;
indicates that map has a key type that is an unknown but specific subtype (inclusive) of Number. In other words, the compiler thinks it could be a Multimap<Integer, String>, or Multimap<Short, String>, or Multimap<Number, String>, etc.  For this reason you can't call map.get(Number), because as far as the compiler knows, it could be a Multimap<Double, String>.
The reason this can't be done is more evident with put.  Should you be able to do put(Number, String) on map?  No, because if it happened to be a Multimap<Integer, String>, you could then add a Double key which will then have violated the integrity of the map.
With the normal Map<K, V> interface, this isn't a problem as get is defined as get(Object), not get(K).
Paul's answer has a great workaround to this situation.  Essentially he is using an intermediate generic method to give the unknown type (in this case represented by capture#5-of ? extends Number) a name (the type parameter T).  This allows you to associate the captures occurring in two different contexts so that you can do something across those contexts.
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