I have two Multimap
s of String
s indexed by (i) Integer
s and (ii) Double
s and a routine to output lists of the String
s.
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