Q:

Java Generics erasure in Multimaps

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?

A:

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.

A:

You should be able to use a generic method to achieve what you want:
public static <T extends Number> void outputNumber(Multimap<T, String> map) {
    for (T key : map.keySet()) {
        Collection<String> strings = map.get(key);
        output(strings);
    }
}

The reason it doesn't work with a wildcard is because ? extends Number means some unknown type that is or extends Number. Meanwhile, Number key could reference some other, incompatible type (for all the compiler knows).

A:

public static void output(Multimap<? extends Number, String> map) {
    for (Collection<String> strings : map.asMap().values()) {
        output(strings);
    }
}

